Search code examples
javascripttimelinevis.jsvis-timeline

How to get the change / delta for start and end values in onMove or onMoving function with vis.js timeline


I have been using onMoving event to trace the changing values of start and end.

How can I find the delta between previous and current values of start and end ?

onMoving: function(item, callback) {

    if (item.start < options.min) item.start = options.min;

    if (item.video_start == 0 && item.segment_start < item.video_start) {
        item.segment_start = item.video_start;
    }

    if (item.video_end > 0 && item.segment_end > item.video_end) {
        item.segment_end = item.video_end;
    }

    callback(item);
    rearrange_timeline_min_max_value();
},

I can see the values with following event, however this is also needed in onMove and onMoving in order to finalize it callback(item) or callback(null).

timeline_items.on('*', function (event, properties) {
    console.log("Properties : " + JSON.stringify(properties));
});

How can I get the delta for start and end with onMoving ?


Solution

  • The item is not updated in the items DataSet until the callback function is called by onMove. You can therefore fetch the existing item from the DataSet within the onMove and onMoving functions and use the original values in your logic.

    onMoving: function(item, callback){
      // Fetch the current item from the DataSet
      let currentItem = items.get(item.id);
      ...
    

    Example is included into the post below and also at https://jsfiddle.net/2gmj8uec/. The example just logs the old start / end times along with the updated ones. When moving the 'From' time doesn't change until a moved event has fired to update the DataSet.

    // DOM element where the Timeline will be attached
    var container = document.getElementById("visualization");
    
    // Create a DataSet (allows two way data-binding)
    var items = new vis.DataSet([
      { id: 1, content: "item 1", start: new Date(2021, 11, 20) },
      { id: 2, content: "item 2", start: new Date(2021, 11, 14) },
      { id: 3, content: "item 3", start: new Date(2021, 11, 18) },
      { id: 4, content: "item 4", start: new Date(2021, 11, 16), end: new Date(2021, 11, 19) },
      { id: 5, content: "item 5", start: new Date(2021, 11, 25) },
      { id: 6, content: "item 6", start: new Date(2021, 11, 27), type: "point" },
    ]);
    
    // Configuration for the Timeline
    var options = {
      editable: true,
      onMoving: function(item, callback){
        // Fetch the current item from the DataSet
        let currentItem = items.get(item.id);
    
        // Log the changes
        console.log("Moving Start - From:", currentItem.start.toISOString(), "To:", item.start.toISOString());
        if(item.end){
          console.log("Moving End - From:", currentItem.end.toISOString(), "To:", item.end.toISOString());
        }
        
        // Return the item, updated if needed
        callback(item);
      },
      onMove: function(item, callback){
        // Fetch the current item from the DataSet
        let currentItem = items.get(item.id);
      
        // Log the changes
        console.log("Moved Start - From:", currentItem.start.toISOString(), "To:", item.start.toISOString());
        if(item.end){
          console.log("Moved End - From:", currentItem.end.toISOString(), "To:", item.end.toISOString());
        }
        
        // Return the item, updated if needed
        // This will result in the items DataSet being updated
        callback(item);
      },
    };
    
    // Create a Timeline
    var timeline = new vis.Timeline(container, items, options);
    body,
    html {
      font-family: sans-serif;
    }
    
    /* Restrict height of console in stackoverflow snippet */
    .as-console-wrapper { max-height: 4em !important; }
    <script src="https://visjs.github.io/vis-timeline/standalone/umd/vis-timeline-graph2d.min.js"></script>
    <link href="https://visjs.github.io/vis-timeline/styles/vis-timeline-graph2d.min.css" rel="stylesheet"/>
    
    <div id="visualization"></div>