Search code examples
javascriptcanvaslooker-studiodeck.js

datastudio, how to remove the canvas when the data change?


I build this custom visuals using deckgl, and after a lot of hurdles made it works, I am not a javascript developper, so I don't really know what I am doing, here is the code

const dscc = require('@google/dscc');
const viz = require('@google/dscc-scripts/viz/initialViz.js');
const local = require('./localMessage.js');
const {Deck} = require ('@deck.gl/core');
const  {ScatterplotLayer} = require('@deck.gl/layers');
//const {Deck, ScatterplotLayer} = deck;
//import {ScatterplotLayer} from '@deck.gl/layers';
// change this to 'true' for local development
// change this to 'false' before deploying
export const LOCAL = false;

// create and add the canvas
var canvasElement = document.createElement('canvas');
// var ctx = canvasElement.getContext('2d');
// canvasElement.id = 'container';
// //document.body.appendChild(canvasElement);


const drawViz = (data) => {

  var height = dscc.getHeight();
  var width = dscc.getWidth();
  // clear the canvas
  var ctx = canvasElement.getContext('2d');

  // clear the canvas.
  ctx.clearRect(0, 0, canvasElement.width, canvasElement.height);

  // set the canvas width and height
  ctx.canvas.width = dscc.getWidth();
  ctx.canvas.height = dscc.getHeight();
  // code
  var data1 = data.tables.DEFAULT;
  var data2 = JSON.stringify(data1);
  var data3 = data2.replace(/\"]/g, "]");
  var data4 = data3.replace(/\["/g, "[");
  var data4 = JSON.parse(data4);
  console.log(data4);
  const INITIAL_VIEW_STATE = {
    bearing: 0,
    longitude: 143.499772,
    latitude:  -34.7773053,
    zoom: 15,
    minZoom: 5,
    maxZoom: 20,
    pitch: 40.5,
  };
new Deck({
  initialViewState: INITIAL_VIEW_STATE,
  controller: true,
  layers: [
    new ScatterplotLayer({
      data : data4,
      getPosition: d => d.coordinateid,
      getRadius: d => d.sizeid,
      getFillColor: d => d.colorid,
    })
  ],

});
};
// renders locally
if (LOCAL) {
  drawViz(local.message);

} else {
  dscc.subscribeToData(drawViz, {transform: dscc.objectTransform});
}

as per the documentation this line should clear the canvas,

ctx.clearRect(0, 0, canvasElement.width, canvasElement.height);

but that does not work, what I get is when I change the data by clicking on a filter, the new layer get rendered as expected but the old layer stay stuck and I can't move it

enter image description here

apparently, I need something to remove the old SVG

I attached a copy of of the report, notice when you filter the previous map is not cleared

datastudio.google.com/reporting/df3d5442-12d7-489e-99fe-90031a7ecc9f

thanks Ralph Spandl for the help, after a lot of messing around, I made it works with

document.body.innerHTML = "";

Solution

  • Every time you resize your visual or make changes to your settings, Data Studio calls your drawViz function. This means each time this line is called

    var canvasElement = document.createElement('canvas');
    

    which basically creates a new canvas tag.

    You must therefor first attempt to delete your canvas tag. My recommendation would be

    document.getElementById("container").remove();
    

    And then create your canvas as you are already doing

    var canvasElement = document.createElement('canvas');
    canvasElement.id = 'container';
    

    Please not that I uncommented the line that applies an ID to your tag. If the visual is created the first time, the tag with the id "container" does not exist, but this has no impact o the rest of your script.

    You can also have a look at the Sunburst example:
    https://github.com/googledatastudio/experimental-visualizations/blob/master/viz/sunburst-drilldown/sunburst/sunburst.js

    The function "prepareDOM" removes all tags and is called before anything else gets drawn.