Custom visualizations: css, common code, hovers, & modifying existing visualizations

I’m just diving in to the world of custom visualizations. A few questions:

  1. Is it possible to link to css files from a custom visualization?
  2. Is it possible to share common code between multiple visualizations? For example, perhaps you have common functionality between 3 different types of bar charts that creates a y-axis. You don’t want to duplicate it in all 3 files. Can you reference a common function that creates a y-axis from various visualization files?
  3. Can we leverage Looker’s hovers in our custom visualizations?
  4. Rather than starting from scratch, I’d like to edit the existing column chart visualization that Looker provides. Where can I find the code Looker uses for its default visualizations?
5 Likes

Also interested in this ability… the ability to inject custom CSS into dashboards especially in embedded scenarios.

+1

1 Like

I’d also like to see more about that from the Looker guys to shed some light on this topic. Is there the possibility to have a Q&A session at some point in the future ?

Hi @sisu_frank_kutzey and @Randy ,

I recommend reaching out to help.looker.com for more information but the short of it is that with custom visualizations, we don’t support it so it’s up to the user to work it out. Which is cool because of the sweet viz’s that can be created outside of looker. However, if they break, we can’t help fix it. We do have some documentation on it here and a public git repo here which I recommend checking out.

Cheers,
Vincent

@ljhaywar A little late to the party but, yes. It’s quite easy :blush:. You can use webpack to do all of this for you. Here is an example of boiler plate custom viz code importing an scss module using the latest versions of TypeScript and Webpack:

Note For a detailed explanation on how to set up a Looker “dev environment” to develop visualizations quickly, checkout my other discourse Creating a Development Environment for Custom Visualizations

pivot-table.ts

import { Looker, VisualizationDefinition } from '../common/types';
import { handleErrors } from '../common/utils';
import './pivot.scss';
declare var looker: Looker;

interface PivotTableVisualization extends VisualizationDefinition {
    elementRef?: HTMLDivElement
}


const vis: PivotTableVisualization = {
    id: 'some_id', // id/label not required, but nice for testing and keeping manifests in sync
    label: 'Some Label',
    options: {
        title: {
            type: 'string',
            label: 'Title',
            display: 'text',
            default: 'Option Name'
        }
    },
    // Set up the initial state of the visualization
    create(element, config) {
        this.elementRef = element;
    },
    // Render in response to the data or settings changing
    update(data, element, config, queryResponse) {
        const errors = handleErrors(this, queryResponse, {
            min_pivots: 0,
            max_pivots: 0,
            min_dimensions: 0,
            max_dimensions: 10,
            min_measures: 0,
            max_measures: 10
        });
        if (errors) { // errors === true means no errors
            // TODO: This is where your code goes to create your
            // custom viz. Let's pretend this code builds an HTML
            // table and appends it to the element 
            // element.appendChild(someFunctionThatBuildsAnHTMLTable());

        }
    }
};

looker.plugins.visualizations.add(vis);

pivot.scss

table {
  width: 100%;
  thead {
    tr {
      th {
        font-weight: 600;
      }
    }
  }
  tbody {
    tr {
      opactiy: 0.7;
      &:hover {
        opacity: 1;
      }
    }
  }
}

webpack.config.js

let path = require('path');

const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

let webpackConfig = {
    entry: {
        pivot: './src/visualizations/pivot-table.ts',
    },
    output: {
        filename: '[name].js',
        path: path.join(__dirname, 'dist'),
        library: '[name]',
        libraryTarget: 'umd'
    },
    resolve: {
        extensions: ['.ts', '.js', '.scss', '.css']
    },
    plugins: [
        new UglifyJSPlugin()
    ],
    module: {
        rules: [
            { test: /\.ts$/, loader: 'ts-loader' },
            { test: /\.css$/, loader: [ 'to-string-loader', 'css-loader' ] },
            { test: /\.scss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'sass-loader',
                ]
            }
        ]
    }
}

module.exports = webpackConfig;

Once you run webpack to bundle everything, it will go through and bundle as it should. At the end of the, you will have a .js file (your custom viz) to upload to looker and it will work as expected. For details on how all of the webpack and typescript work together and the development flow, checkout https://github.com/looker/custom_visualizations_v2

So to answer the questions:

  1. Is it possible to link to css files from a custom visualization?
    Yes, use a bundler such as Webpack

  2. Is it possible to share common code between multiple visualizations? For example, perhaps you have common functionality between 3 different types of bar charts that creates a y-axis. You don’t want to duplicate it in all 3 files.
    Yes, this is easily done through creating JS modules or using TypeScript. You can also just create a separate JS file for your common code and just import that library/code into wherever you need it. If done correctly, webpack will take care of the rest

  3. Can you reference a common function that creates a y-axis from various visualization files?
    This would be the same thing as sharing code (question 2)

  4. Can we leverage Looker’s hovers in our custom visualizations?
    Not sure about this one but this can easily be achieved via CSS/JS in your custom viz code

  5. Rather than starting from scratch, I’d like to edit the existing column chart visualization that Looker provides. Where can I find the code Looker uses for its default visualizations?
    This would be cool

2 Likes