从 SignalR 事件调用 Plotly.restyle 时,Plotly 会引发 TypeError

Posted

技术标签:

【中文标题】从 SignalR 事件调用 Plotly.restyle 时,Plotly 会引发 TypeError【英文标题】:Plotly throws a TypeError when calling Plotly.restyle from a SignalR event 【发布时间】:2021-11-20 16:20:35 【问题描述】:

我是 Plotly 的新手,我正在尝试做一个非常简单的 PoC 来根据 SignalR (WebSocket) 事件实时更新绘图。

我在一支可以正常工作的 Pen 中有以下内容:

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);

我现在正在尝试让它在 Vue+SignalR 上下文中工作:

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
;

我传递给restyleresult 与Pen 中的[['1', '2', '3']] 相同。

抛出的错误是:

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)

我在网上找不到任何东西来告诉我可能导致错误的原因。我在这两种情况下都使用plotly-2.4.2.min.js,并尝试了其他版本,结果相同。 该错误来自 htmlElement 由于某种原因丢失其data 属性。

【问题讨论】:

【参考方案1】:

Vue(我不熟悉)似乎发生了一些事情,它杀死了 HTMLElement 的 .data 属性。我试过这段代码:

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);

第一次需要重新创建绘图,但以下消息有效,.data 属性具有预期值。

最后,由于我不需要 Vue(它来自我正在使用的 Microsoft 示例),我删除了所有与 Vue 相关的代码,并且代码可以像在 CodePen 中一样正常工作。

【讨论】:

以上是关于从 SignalR 事件调用 Plotly.restyle 时,Plotly 会引发 TypeError的主要内容,如果未能解决你的问题,请参考以下文章

从 SignalR 调用特定客户端

如何从SignalR客户端端确定服务器断开连接

是否可以从 Postman 调用 SignalR Hub

从 Controller 调用 SignalR Core Hub 方法

SignalR - 从服务器端代码调用 Hub 类方法(存在于单独的 MVC 项目中)

建立连接时的 SignalR Core 调用函数