在 Spotfire Mods 中是否可以检查 reader 中更新或更改的内容?

In Spotfire Mods is it possible to check what has updated or changed in the reader?

我有一个使用 Spotfire Mods 使用 d3 构建的网络图表。它具有在 mods 清单中定义的多个属性,以及从 Spotfire 传递到 mod.

的数据

我的reader定义为:

/**
* Create the read function.
*/
const reader = mod.createReader(
    mod.visualization.data(), 
    mod.windowSize(), 
    mod.property("network_strength"), 
    mod.property("display_labels"),
    mod.property("network_type"),
    mod.property("apply_color"),
);

我的渲染函数看起来像:

/**
 * Initiate the read loop
 */
reader.subscribe(render);

/**
 * @param {Spotfire.DataView} dataView
 * @param {Spotfire.Size} windowSize
 * @param {Spotfire.ModProperty<integer>} network_strength
 * @param {Spotfire.ModProperty<boolean>} display_labels
 * @param {Spotfire.ModProperty<string>} network_type
 * @param {Spotfire.ModProperty<string>} apply_color
 */
async function render(dataView, windowSize, network_strength, display_labels, network_type, apply_color) {

但是,如果数据或 reader 中的任何属性发生任何变化,则整个网络需要重新渲染,因为没有办法知道发生了什么变化,网络是否需要重新渲染模拟。

有没有办法确定数据或 属性 是否已更改,以便我控制要更新的内容?例如,如果有人只更改 display_labelsapply_color 属性,那么我可以只更改现有网络图表的设置,而不必重新绘制网络。

感谢您的帮助!

您可以检查订阅回调参数的引用是否与其先前的值相等。 reader 仅从服务器获取更改的值并将它们传递给订阅回调。保持不变的值并在参考水平上相等。

这是一个围绕 reader 的小包装函数,它通过 reader.hasValueChanged(value) 方法添加了此引用检查功能。出于比较原因,它保留对先前传递的参数的引用。如果引用检查失败,则表示该值是来自服务器的新值。

/**
* Wrap a reader and adds an additional method called `hasChanged`.
* It allows you to check whether a passed argument is new or unchanged since the last time the subscribe loop was called.
* @function
* @template A
* @param {A} reader
* @returns {A & {hasValueChanged(value: any):boolean}}
*/
function readerWithChangeChecker(reader) {
    let previousValues = [];
    let currentValues = [];

    function storeValuesForComparison(cb) {
        return function storeValuesForComparison(...values) {
            previousValues = currentValues;
            currentValues = values;
            return cb(...values);
        };
    }

    return {
        ...reader,
        subscribe(cb) {
            reader.subscribe(storeValuesForComparison(cb));
        },
        hasValueChanged(value) {
            return previousValues.indexOf(value) == -1;
        }
    };
}

// Pass an already created reader as the argument to the wrapper function.
let reader = readerWithChangeChecker(
    mod.createReader(
       mod.visualization.data(), 
        mod.windowSize(), 
        mod.property("network_strength"), 
        mod.property("display_labels"),
        mod.property("network_type"),
        mod.property("apply_color")
    )
);

reader.subscribe(async (dataview, size, networkStrength, networkType, applyColor) => {
    console.log("Dataview", reader.hasValueChanged(dataview));
    console.log("size", reader.hasValueChanged(size));
    console.log("network_strength", reader.hasValueChanged(networkStrength));
    console.log("display_labels", reader.hasValueChanged(networkType));
    
    // Use the added method to optimize your render code.
    if(reader.hasValueChanged(applyColor)) {
        console.log("apply_color has changed")    
    }

    await dataview.allRows();
});

有关 reader 的更多信息,请参阅以下资源。