update(ids, changedData, oldData) {
    const nodes = this.body.nodes;
    let dataChanged = false;
    for (let i = 0; i < ids.length; i++) {
      const id = ids[i];
      let node = nodes[id];
      const data = changedData[i];
      if (node !== undefined) {
        // update node
        if (node.setOptions(data)) {
          dataChanged = true;
        }
      } else {
        dataChanged = true;
        // create node
        node = this.create(data);
        nodes[id] = node;
      }
    }

    if (!dataChanged && oldData !== undefined) {
      // Check for any changes which should trigger a layout recalculation
      // For now, this is just 'level' for hierarchical layout
      // Assumption: old and new data arranged in same order; at time of writing, this holds.
      dataChanged = changedData.some(function (newValue, index) {
        const oldValue = oldData[index];
        return oldValue && oldValue.level !== newValue.level;
      });
    }

    if (dataChanged === true) {
      this.body.emitter.emit("_dataChanged");
    } else {
      this.body.emitter.emit("_dataUpdated");
    }
  }
Update existing nodes, or create them when not yet existing
@param {number[] | string[]} ids id's of changed nodes
@param {Array} changedData array with changed data
@param {Array|undefined} oldData optional; array with previous data
@private