Posible issue in Plotly.relayout and passing in an update object with a shapes array

Using plotly version 1.39.4 vs newer versions

Take a look at this codepen
https://codepen.io/anon/pen/ZMgyRv?editors=1111

While using a version <= 1.39.4, plotly.relayout accepts an update object with an array of shapes to paint.

If you use a newer version, a warning appears in the console: “WARN: unrecognized full object value”.

I still don’t know if this causes some other problems, while interacting with the shapes in the chart (I use edits->shapePosition:true)…

Thanks very much for the report.

I cut a few too many things in https://github.com/plotly/plotly.js/pull/2823

Working on a fix now.

Thanks to you and to the team behind plotly :wink:

EDIT: I’m running 1.41.3

Hey @etienne was this ever sorted out? I’m getting the warning whenever I try to run relayout with an array of annotations. Here an example of my updates:

{
  "yaxis": {
    "automargin": true,
    "showgrid": false,
    "showline": true,
    "showticklabels": true,
    "zeroline": false,
    "range": [
      30,
      50
    ],
    "title": "Index"
  },
  "annotations": [
    {
      "bgcolor": "white",
      "bordercolor": "rgba(0, 0, 0, 0.65)",
      "borderpad": 2,
      "borderwidth": 2,
      "captureevents": true,
      "font": {
        "color": "rgba(0, 0, 0, 0.65)",
        "size": 12
      },
      "hovertext": "Buzz Median: 15",
      "showarrow": false,
      "text": "<b>Buzz Median</b>",
      "textangle": 90,
      "x": 15,
      "y": 0.95,
      "yref": "paper"
    },
    {
      "bgcolor": "white",
      "bordercolor": "rgba(0, 0, 0, 0.65)",
      "borderpad": 2,
      "borderwidth": 2,
      "captureevents": true,
      "font": {
        "color": "rgba(0, 0, 0, 0.65)",
        "size": 12
      },
      "hovertext": "Index Median: 37",
      "showarrow": false,
      "text": "<b>Index Median</b>",
      "textangle": 0,
      "y": 37,
      "x": 0.95,
      "xref": "paper"
    }
  ]
}

It seems to work fine with newPlot. If there’s anything else I can do to help, let me know!

Just for reference, it’s adding not just relayout with annotations, but any array (as @fjrial indicated). My work around (for now) is to transpose the array to string attributes before calling relayout:

function myRelayout(updates) {
  // copy so we don't mess with someone else's object
  let layoutUpdates = { ...updates };

  if (updates.annotations) {
    // add annotations[0], annotations[1], ..., annotations[n] to our update object
    // to our copy
    layoutUpdates = updates.annotations.reduce((result, annotation, index) => ({
      ...result,
      [`annotations[${index}]`]: annotation,
    }), layoutUpdates);
    // get rid of annotations from our copy
    delete layoutUpdates.annotations;
  }

  Plotly.relayout(myChart, layoutUpdates);
}

Not sure if this is more or less elegant, but I rewrote it just now to take any array value and create indicied values:

function myRelayout (updates) {
  const layoutUpdates = { ...updates };
    const arrayUpdates = {};

    Object.keys(layoutUpdates).forEach((key) => {
      if (Array.isArray(layoutUpdates[key])) {
        layoutUpdates[key].forEach((update, index) => {
          arrayUpdates[`${key}[${index}]`] = update;
        });
        delete layoutUpdates[key];
      }
    });

    Plotly.relayout(this._chart, {
      ...layoutUpdates,
      ...arrayUpdates,
    });
}

This can obviously be refactored any way you want, but the general idea is to find the arrays, create ${key}[${index}] = value values in your updates object and use them when calling relayout

Yes, this is fixed in 1.42.5