I'm new to Plotly and I'm trying to do a very simple PoC to update a plot in real-time based on SignalR (WebSocket) events.
I have the following in a Pen that works just fine:
var data = [
{
x: ['giraffes', 'orangutans', 'monkeys'],
y: [20, 14, 23],
type: 'bar'
}
];
Plotly.newPlot('myDiv', data);
setTimeout(() => {
const newData = "\"1,2,3\""; // data is received like this in SignalR
const data = newData.replace(/"/g,"");
const result = [data.split(',')];
Plotly.restyle('myDiv', 'y', result);
}, 2000);
I'm trying now to get it to work in a Vue+SignalR context:
const plotData = [
{
x: ['giraffes', 'orangutans', 'monkeys'],
y: [1, 1, 1],
type: 'bar'
}
];
Plotly.react('testplot', plotData);
const app = new Vue({
el: '#app',
data: data,
methods: { ... }
);
//...
const connection = new signalR.HubConnectionBuilder()
.withUrl(apiBaseUrl + '/api', {
accessTokenFactory: () => {
return generateAccessToken(data.username)
}
})
.configureLogging(signalR.LogLevel.Information)
.build();
connection.on('newMessage', onNewMessage);
//...
function onNewMessage(message) {
const data = message.Text.replace(/"/g, "");
const result = [data.split(',')];
Plotly.restyle('testplot', 'y', result); --> error here
};
The result I'm passing to restyle is the same as in the Pen, [['1', '2', '3']].
The error thrown is:
Uncaught TypeError: Cannot read properties of undefined (reading 'map')
at Object.r.coerceTraceIndices (plotly-2.4.2.min.js:58)
at Object.D [as restyle] (plotly-2.4.2.min.js:58)
at HubConnection.onNewMessage (index:207)
at HubConnection.ts:367
at Array.forEach (<anonymous>)
at HubConnection.invokeClientMethod (HubConnection.ts:367)
at HubConnection.processIncomingData (HubConnection.ts:297)
at WebSocketTransport.HubConnection.connection.onreceive (HubConnection.ts:54)
at WebSocket.webSocket.onmessage (WebSocketTransport.ts:56)
I cannot find anything online to tell me what could cause the error. I'm using plotly-2.4.2.min.js in both cases and have tried other versions with the same result.
The error comes from the HTMLElement losing its data attribute for some reason.
It seems like something happens with Vue (which I'm not familiar with) that kills the .data property of the HTMLElement. I tried with this code:
var testPlotElemenet = document.getElementById('testplot');
if (testPlotElemenet.data) {
Plotly.restyle(testPlotElemenet, 'y', result);
}
else {
var testData = [
{
x: ['giraffes', 'orangutans', 'monkeys'],
y: [20, 14, 23],
type: 'bar'
}
];
Plotly.react(testPlotElemenet, testData);
Plotly.restyle(testPlotElemenet, 'y', result);
}
And the first time it needs to recreate the plot, but the following messages work and the .data property has the expected values.
In the end, since I don't need Vue (it was there from a Microsoft example I was using), I removed all Vue related code and the code works just fine as in CodePen.