I am trying to implement a custom transform to use it in Vega.
For now, the transform is simple (it just doubles the data passed in input). These are the two files I am using:
This is the index.html file:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="script.js" defer></script>
</head>
<body>
<div id="vis"></div>
</body>
</html>
While this is the script.js file:
window.onload = () => {
console.log("Script start");
// =============================================
// 1. REGISTER CUSTOM TRANSFORM (GLOBAL SCOPE)
// =============================================
function DoubleValueTransform(params) {
vega.Transform.call(this, [], params); // Initialize superclass
console.log("DoubleValueTransform Constructor");
}
DoubleValueTransform.prototype = Object.create(vega.Transform.prototype);
DoubleValueTransform.prototype.constructor = DoubleValueTransform;
DoubleValueTransform.Definition = {
"type": "DoubleValueTransform",
"metadata": {"modifies": true},
"params": [
{ "name": "factor", "type": "number", "default": 2 }
]
};
// Implement transformation logic
DoubleValueTransform.prototype.transform = function (_, pulse) {
console.log("Inside the transform");
const factor = _.factor || 2;
pulse.visit(pulse.SOURCE, d => {
d.value = d.value * factor;
console.log("Value transformed:", d.value);
});
return pulse.reflow();
};
// Register the custom transform
vega.transforms["DoubleValueTransform"] = DoubleValueTransform;
if (!vega.schema) {
vega.schema = {};
}
if (!vega.schema.transforms) {
vega.schema.transforms = {};
}
vega.schema.transforms["DoubleValueTransform"] = DoubleValueTransform.Definition;
console.log("Custom transform registered:", vega.transforms["DoubleValueTransform"]);
// =============================================
// 2. SPECIFICATION
// =============================================
const spec = {
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 400,
"height": 200,
"padding": 5,
"signals": [
{
"name": "progress",
"value": 0,
"bind": {"input": "range", "min": 0, "max": 100},
"on": [{"events": {"signal": "timer"}, "update": "(progress + 1) % 100"}]
},
{
"name": "timer",
"value": 0,
"on": [{"events": {"type": "timer", "delay": 100}, "update": "timer + 1"}]
}
],
"data": [
{
"name": "table",
"values": [
{"category": "A", "value": 30},
{"category": "B", "value": 80},
{"category": "C", "value": 45}
],
"transform": [
{
"type": "DoubleValueTransform", // Custom transform
"factor": 2
},
{
"type": "filter",
"expr": "datum.value <= progress"
}
]
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {"data": "table", "field": "category"},
"range": "width",
"padding": 0.05
},
{
"name": "yscale",
"domain": {"data": "table", "field": "value"},
"nice": true,
"range": "height"
}
],
"axes": [
{"orient": "bottom", "scale": "xscale"},
{"orient": "left", "scale": "yscale"}
],
"marks": [
{
"type": "rect",
"from": {"data": "table"},
"encode": {
"enter": {
"x": {"scale": "xscale", "field": "category"},
"width": {"scale": "xscale", "band": 0.5},
"y": {"scale": "yscale", "field": "value"},
"y2": {"scale": "yscale", "value": 0},
"fill": {"value": "steelblue"}
}
}
}
]
};
// =============================================
// 3. PARSE SPEC AND RENDER VIEW
// =============================================
const runtime = vega.parse(spec);
const view = new vega.View(runtime)
.logLevel(vega.Info)
.renderer('canvas')
.initialize('#vis')
.hover()
.run();
window.view = view;
};
When I start a server, trying to visualize the results, nothing is visualized and, instead, I get these messages in the console:
Script start script.js:3
script.js:52 Custom transform registered: ƒ DoubleValueTransform(params) {
vega.Transform.call(this, [], params); // Inizializza la superclasse
console.log("DoubleValueTransform Constructor");
}
[email protected]:1 Uncaught Error: Unrecognized transform type: "DoubleValueTransform"
at u ([email protected]:1:560)
at sU ([email protected]:1:476852)
at [email protected]:1:487956
at Array.forEach (<anonymous>)
at TU ([email protected]:1:487936)
at [email protected]:1:497845
at Array.forEach (<anonymous>)
at uL ([email protected]:1:497833)
at lL ([email protected]:1:499276)
at t.parse ([email protected]:1:506807)
It feels like the transform is registered, but I really don’t know how to bypass this error. Could this be a synchronicity issue? I am not very familiar with the low-level Vega grammar.