Skip to content
This repository has been archived by the owner on Nov 19, 2019. It is now read-only.

orderSubgroups seems to be using "old" information for ordering #127

Open
mpf82 opened this issue Feb 18, 2019 · 2 comments
Open

orderSubgroups seems to be using "old" information for ordering #127

mpf82 opened this issue Feb 18, 2019 · 2 comments
Labels
bug Something isn't working

Comments

@mpf82
Copy link

mpf82 commented Feb 18, 2019

I'm using a custom ordering function to order the subgroups alphabetically. However, when I update the subgroup of item 7 from B to C with items.update( item ) it seems that internally the item has not yet updated when orderSubgroups is called.

var subgroupOrderFn = function (a,b) {
    console.log("subgroupOrderFn", a.subgroup, b.subgroup, a.subgroup.charCodeAt(0) - b.subgroup.charCodeAt(0));
    return a.subgroup.charCodeAt(0) - b.subgroup.charCodeAt(0);
};
var groups = new timeline.DataSet([
    { id: 'foo', content:'foo', subgroupOrder: subgroupOrderFn, },
]);
var items = new timeline.DataSet({
    type: { start: 'ISODate', end: 'ISODate' }
});
items.add([
    {id: 7, content: 'B', start: '2014-01-19', end: '2014-01-20',group:'foo', subgroup:'B'},
    {id: 17, content: 'A', start: '2014-01-20', end: '2014-01-22',group:'foo', subgroup:'A'},
]);

setTimeout(function(){
    var item = {id: 7, content: 'C', subgroup:'C'};
    items.update( item );
}, 2000);

As a result, I get an exception:

timeline.js:10126 Uncaught TypeError: Cannot set property 'index' of undefined
    at Group.orderSubgroups (timeline.js:10126)
    at Group.changeSubgroup (timeline.js:10468)
    at RangeItem.setData (timeline.js:3414)
    at ItemSet._updateItem (timeline.js:17416)
    at timeline.js:17127
    at Array.forEach (<anonymous>)
    at ItemSet._onUpdate (timeline.js:17110)
    at Object.update [as callback] (timeline.js:16042)
    at DataSet._trigger (timeline.js:5184)
    at DataSet.update (timeline.js:5289)

The output of the console.log in my ordering function is:

subgroupOrderFn A B -1

So you can see, it's still B instead of C.

I have also added console.log messages to orderSubgroups:

...
    if (sortArray.length > 0) {
      console.log("sortArray", sortArray);
      console.log("this.subgroups", this.subgroups);
      for (var i = 0; i < sortArray.length; i++) {
        this.subgroups[sortArray[i].subgroup].index = i;
      }
    }
...

sortArray:

[
  {
    "id": 17,
    "content": "A",
    "start": "2014-01-20T00:00:00.000Z",
    "end": "2014-01-22T00:00:00.000Z",
    "group": "foo",
    "subgroup": "A"
  },
  {
    "id": 7,
    "content": "B",
    "start": "2014-01-19T00:00:00.000Z",
    "end": "2014-01-20T00:00:00.000Z",
    "group": "foo",
    "subgroup": "B"
  }
]

this.subgroups (only relevant parts):

{
   A: { ... },
   C: { <-- !!! correct
      items: [
         {
           "id": 7,
           "content": "B", <-- !!! still old value
           "start": "2014-01-19T00:00:00.000Z",
           "end": "2014-01-20T00:00:00.000Z",
           "group": "foo",
           "subgroup": "B" <-- !!! still old value
         }
      ]
   }
}

As you can see, the item still has the old value, while the group has been updated correctly.

I'm using version 2.3.4


Additional info: The problem does not exist, if another item with subgroup C already exists during the initial creation of the timeline. It only happens if I change the item's subgroup to a subgroup that's not yet present.

@yotamberk yotamberk added the bug Something isn't working label Feb 19, 2019
@yotamberk
Copy link
Owner

Can you please attach a jsbin with the issue?

@mpf82
Copy link
Author

mpf82 commented Feb 20, 2019

https://jsbin.com/qogoxiweko/1/edit?html,js,console,output

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://unpkg.com/timeline-plus/dist/timeline.css">
    
    <script src="https://momentjs.com/downloads/moment.min.js"></script>
    <script src="https://momentjs.com/downloads/moment-timezone-with-data.min.js"></script>
    <script src="https://unpkg.com/timeline-plus/dist/timeline.js"></script>    
  </head>
  <body>
    <div id="viz"></div>
  </body>
</html>

var container = document.getElementById('viz');

var items = new timeline.DataSet({
    type: { start: 'ISODate', end: 'ISODate' }
});
var subgroupOrderFn = function (a,b) {
    console.log("subgroupOrderFn", a.subgroup, b.subgroup, a.subgroup.charCodeAt(0) - b.subgroup.charCodeAt(0));
    return a.subgroup.charCodeAt(0) - b.subgroup.charCodeAt(0);
};
var groups = new timeline.DataSet([
    { id: 'foo', content:'foo', subgroupOrder: subgroupOrderFn, },
]);
items.add([
    {id: 7, content: 'B', start: '2014-01-19', end: '2014-01-20',group:'foo', subgroup:'B'},
    {id: 17, content: 'A', start: '2014-01-20', end: '2014-01-22',group:'foo', subgroup:'A'},
]);

var options = {
        editable: true,
        groupOrder: 'id', 
        groupEditable: true,
        orientation: 'both', 
        stack: false, 
        stackSubgroups: true,
        type: 'range',
};

var TL;
setTimeout(function(){
  TL = new timeline.Timeline(container, items, groups, options);
}, 500);

setTimeout(function(){
    // orderSubgroups seems to be using "old" information for ordering
    // https://github.com/yotamberk/timeline-plus/issues/127
    var item = {id: 7, content: 'C', subgroup:'C'};
    items.update( item );
}, 3000); 

I'm not sure though, why stacking subgroups does not work in the jsbin, it's working fine in my environment. But that's not the issue here.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants