Create Data Studio Community Visualizations with dscc-gen

1. Intro

Google Data Studio lets you build dynamic, interactive dashboards with beautiful data visualizations, for free. Community visualizations are a feature for Data Studio that allows you to build custom visualizations with JavaScript that integrate with your Data Studio reports.

What you'll learn

In this codelab, you'll learn:

  • How a Google Data Studio Community Visualization works
  • How to build a Community Visualization with our command-line template tool
  • How to use JavaScript visualization libraries to build Community Visualizations
  • How to integrate your Community Visualization into a Data Studio dashboard

What you'll need

To complete this codelab, you'll need:

  • Access to the internet, a web browser, and a terminal, and your favorite text editor
  • A Google account
  • Access to a Google Cloud Storage bucket
  • Familiarity with Javascript, Node.js, and the command-line

This codelab assumes:

  • You've already built a Community Visualization (TODO link first codelab)
  • Are familiar with Google Cloud Storage

To get started, make a copy of this report by clicking 14575f934e800122.png in the upper-right hand corner. Keep it open in another tab as you go through the codelab.

2. Quick Survey

Why did you choose this codelab?

I am interested in data visualization in general. I want to learn more about Data Studio I want to build my own Community Visualization. I am trying to integrate Data Studio with another platform. I am interested in Google Cloud solutions.

How do you plan to use this codelab/tutorial?

Read it and complete the exercises Skim through only

How would you rate your experience with Data Studio?

Never heard of it I know what it is but I don't use it. I use it regularly. I am an expert user.

What best describes your background?

Developer Business / Data Analyst Data Scientist / Data Engineer Financial Analyst Marketing / Social Media / Digital Analytics Expert Business Analyst Designer Other

Move to the next page to submit survey information.

3. Community Visualization development with dscc-gen

dscc-gen

dscc-gen is a command-line tool that provides opinionated templates and workflows for Community Visualizations and Community Connectors. The Community Visualization template provides a working visualization and a workflow that allows you to immediately see your visualization code changes, and scripts to validate, build, and deploy your visualizations.

Setup

dscc-gen uses gsutil in deployment scripts, and npm and webpack to build Community Visualization JavaScript code.

  1. Install npm on your local computer
  2. Go through the gsutil quickstart and set up a Google Cloud Storage bucket
  3. Navigate to a local directory where you want to locate your project

4. Start a new dscc-gen Community Visualization project

Open a terminal and run the command:

npx @google/dscc-gen viz

dscc-gen will prompt you for a project name, a "dev" GCS storage location, and a "prod" storage location. Enter the location as a URI with the gs protocol, e.g. gs://my-gs-project/example-dev. A "location" can either be a Cloud Storage bucket or a folder within that bucket. The two storage locations must be different. The tool will validate that you have access to the values you enter. If the locations do not exist, they will be created for you.

Once dscc-gen has created a new Community Visualization, it prints instructions on how to get started. Your terminal will look something like this (your input in bolded italics):

$ npx @google/dscc-gen viz
npx: installed 345 in 14.957s
? Project name barchart
? What is your GCS dev directory? gs://community-visualizations-codelab/barchart-dev
? What is your GCS prod directory? gs://community-visualizations-codelab/barchart-prod
Installing dependencies...

Created new community viz: barchart

cd barchart and npm run start to begin working on your viz!

You will edit the files in src/ - specifically, index.js, index.json, and index.css - to write your visualization.

The files in dist/ allow you to preview your visualization locally in a browser. webpack.config.js is used for running the visualization locally. README.md provides an overview of the template files and commands.

5. Preview your visualization locally

Follow the suggested instructions and run the following commands in your terminal:

cd <folder name>

npm run start

A browser will open with a web page that looks like this:

2f219993dfb676d4.png

Learn more in the next step.

6. [Info] How the dscc-gen workflow is intended to work

The dscc-gen visualization template comes with a working visualization, and instructions on how to use the template. Here's the main functionality:

Update your local message: Sample message is included in the template, but it's likely not reflective of the use case you want to support. You should download sample data reflective of the visualization you want to build.

Local development workflow: Using the data from Update your local data, write and test your code locally.

Build & deploy your visualization: Build your code & upload it to your Google Cloud Storage buckets.

Load your viz in Data Studio: Add the visualization into your Data Studio report.

7. Define a config

The configuration file is the contract between you (the viz developer) and the report editor who uses the visualization. It defines options available once the visualization is loaded into Data Studio.

For this bar chart visualization, the config will have one dimension and one metric, as well as a style element that allows the report editor to change the bar chart style.

Replace the contents of src/index.json with the following. Make sure you include all brackets. If you're retyping it, make sure you pay attention to the difference between square and curly brackets and the nesting structure.

index.json

{
  "data": [
    {
      "id": "concepts",
      "label": "Concepts",
      "elements": [
        {
          "id": "dimension",
          "label": "Dimensions",
          "type": "DIMENSION",
          "options": {
            "min": 1,
            "max": 1
          }
        },
        {
          "id": "metric",
          "label": "Metric",
          "type": "METRIC",
          "options": {
            "min": 1,
            "max": 1
          }
        }        
      ]
    }
  ],
  "style": [
    {
      "id": "barStyling",
      "label": "Bar Styles",
      "elements": [
        {
          "id": "barColor",
          "label": "Bar Color",
          "type": "FILL_COLOR",
          "defaultValue": {
            "color": "#1E555C"
          }
        }
      ]
    }
  ]  
}

8. Download updated message

To update your locally stored data, run:

npm run update_message

Your terminal should look something like this:

barchart $ npm run update_message
> @ update message /Users/Code/barchart
> dscc-scripts viz update_message -f object

Copying file://build/index.js [Content-Type=application/javascript]...
Copying file://build/index.css [Content-Type=text/css]...
Copying file://build/manifest.json [Content-Type=application/json]...
Copying file://build/index.json [Content-Type=application/json]...
\ [4 files][ 48.5 KiB/ 48.5 KiB]
Operation completed over 4 objects/48.5 KiB.
Viz deployed to gs://community-visualizations-codelabs/barchart-dev

This command deploys a visualization to Data Studio that prints the data received to a local viz. The scripts print out the deployment location of your visualization (highlighted above). You'll use this location to load your visualization in Data Studio.

To load your visualization, open the report you copied earlier.

  1. Go to "edit report"
  2. Click on "Community visualizations and components" in the toolbar

e927f8fbd49979a5.png

  1. Click "Explore more"

c236b0cfcc68ce2c.png

  1. Click "Build your own visualization"
  2. Enter your manifest path (the gs://... location printed out in your terminal) and click Submit

26588c6c8382a3b.png

  1. Click on the rendered card to add it to your report

The visualization should render JSON that looks something like this:

a08a61345fe12837.png

Copy the whole message by right-clicking and selecting all, and replace the contents of src/localMessage.js with what you just copied. Save the file.

The visualization running locally in your browser should no longer show up, and if you look in the console, you'll see an error.

9. Write JavaScript for a bar chart

First, run the following command to add d3.js as a dependency.

npm install d3

Then, replace src/index.js with the following code. Changes from the last step are bolded.

src/index.js

const d3 = require('d3');
const dscc = require('@google/dscc');
const local = require('./localMessage.js');

// change this to 'true' for local development
// change this to 'false' before deploying
export const LOCAL = true;

const drawViz = (message) => {
  const margin = { left: 20, right: 20, top: 20, bottom: 20 };
  const height = dscc.getHeight() - 10;
  const width = dscc.getWidth();

  const chartHeight = height - margin.top - margin.bottom;
  const chartWidth = width - margin.left - margin.right;

  // remove existing svg
  d3.select("body")
    .selectAll("svg")
    .remove();

  // make a canvas
  const svg = d3
    .select("body")
    .append("svg")
    .attr("width", width)
    .attr("height", height);

  // make an svg for the bar chart
  const chartSvg = svg
    .append("svg")
    .attr("x", margin.left)
    .attr("y", margin.top)
    .attr("width", chartWidth)
    .attr("height", chartHeight);

  // xScale to distribute bars
  const xScale = d3
    .scaleBand()
    .domain(message.tables.DEFAULT.map(d => d.dimension[0]))
    .range([0, chartWidth])
    .paddingInner(0.3);

  // yScale to size bars
  const yScale = d3
    .scaleLinear()
    .domain([0, d3.max(message.tables.DEFAULT.map(d => d.metric[0]))])
    .range([0, chartHeight]);

  // add bars
  const bars = chartSvg
    .append("g")
    .attr("class", "bars")
    .selectAll("rect.bars")
    .data(message.tables.DEFAULT)
    .enter()
    .append("rect")
    .attr("x", d => xScale(d.dimension[0]))
    .attr("y", d => chartHeight - yScale(d.metric[0]))
    .attr("width", xScale.bandwidth())
    .attr("height", d => yScale(d.metric[0]));

  // add text
  const text = svg
    .append("g")
    .selectAll("text")
    .data(message.tables.DEFAULT)
    .enter()
    .append("text")
    .attr(
      "x",
      d => xScale(d.dimension[0]) + xScale.bandwidth() / 2 + margin.left
    )
    .attr("y", height - margin.bottom / 4)
    .attr("text-anchor", "middle")
    .text(d => d.dimension[0]);
};

// renders locally
if (LOCAL) {
  drawViz(local.message);
} else {
  dscc.subscribeToData(drawViz, {transform: dscc.objectTransform});
}

If the local server is still running, check your browser. The local development web page should now show a bar chart, like the one below.

2cb9f9d8d1bd2063.png

10. Update manifest (optional)

Your visualization manifest contains metadata about your visualization, as well as the location of your visualization JavaScript, config, and CSS. Update the values in your manifest - they will be used to provide the end user information about your visualization.

Edit src/manifest.json to describe your visualization. A sample manifest is below.

src/manifest.json

{
  "name": "Bar Chart",
  "organization": "[My name]",
  "description": "Bar chart",
  "logoUrl": "https://storage.googleapis.com/community-visualizations-codelabs/barchart/bar_chart.png",
  "organizationUrl": "https://github.com/googledatastudio/",
  "supportUrl": "http://github.com/googledatastudio/community-visualizations",
  "privacyPolicyUrl": "http://github.com/googledatastudio/community-visualizations",
  "termsOfServiceUrl": "http://github.com/googledatastudio/community-visualizations",
  "packageUrl": "",
  "devMode": "DEVMODE_BOOL",
  "components": [
    {
      "id": "Bar chart",
      "name": "Bar chart",
      "description": "My first Community Visualization",
      "iconUrl": "https://storage.googleapis.com/community-visualizations-codelabs/table/table_icon.png",
      "resource": {
        "js": "YOUR_GCS_BUCKET/index.js",
        "config": "YOUR_GCS_BUCKET/index.json",
        "css": "YOUR_GCS_BUCKET/index.css"
      }
    }
  ]
}

11. Deploy the visualization

In src/index.js, change const LOCAL to "false". The visualization in your browser should stop working. The changed line of code is in bold. This boolean configures whether or not the code should use a "local" data file or the data received from Data Studio.

src/index.js (abridged)

const d3 = require('d3');
const dscc = require('@google/dscc');
const local = require('./localMessage.js');

// change this to 'true' for local development
// change this to 'false' before deployment
export const LOCAL = false;

const drawViz = (message) => {...}

Then, in your terminal, run:

npm run build:dev
npm run push:dev

The build:dev command bundles your JavaScript dependencies into an unminified output, and replaces the values in your manifest to disable caching and to point to the "dev" bucket that you configured earlier.

The push:dev command uploads your visualization resources to the "dev" bucket that you configured in step 1, and prints the bucket location to the console..

Refresh the Data Studio report. You should see a bar chart. Try changing the data and style options in the property panel. Changing the data will change the bars. However, the bar color style selector will not yet work.

12. Use report editor color selections in the bar chart

To edit the code locally, first update the const LOCAL variable in src/index.js to true. Then, add a new function called styleVal(), and update the code in drawViz(). Your src/index.js should look like this:

src/index.js

const d3 = require('d3');
const dscc = require('@google/dscc');
const local = require('./localMessage.js');

// change this to 'true' for local development
// change this to 'false' before deploying
export const LOCAL = false;

// parse the style value
const styleVal = (message, styleId) => {
  if (typeof message.style[styleId].defaultValue === "object") {
    return message.style[styleId].value.color !== undefined
      ? message.style[styleId].value.color
      : message.style[styleId].defaultValue.color;
  }
  return message.style[styleId].value !== undefined
    ? message.style[styleId].value
    : message.style[styleId].defaultValue;
};

const drawViz = message => {
  const margin = { left: 20, right: 20, top: 20, bottom: 20 };
  const height = dscc.getHeight() - 10;
  const width = dscc.getWidth();

  const chartHeight = height - margin.top - margin.bottom;
  const chartWidth = width - margin.left - margin.right;

  // remove existing svg
  d3.select("body")
    .selectAll("svg")
    .remove();

  // make a canvas
  const svg = d3
    .select("body")
    .append("svg")
    .attr("width", width)
    .attr("height", height);

  // make an svg for the bar chart
  const chartSvg = svg
    .append("svg")
    .attr("x", margin.left)
    .attr("y", margin.top)
    .attr("width", chartWidth)
    .attr("height", chartHeight);

  // xScale to distribute bars
  const xScale = d3
    .scaleBand()
    .domain(message.tables.DEFAULT.map(d => d.dimension[0]))
    .range([0, chartWidth])
    .paddingInner(0.3);

  // yScale to size bars
  const yScale = d3
    .scaleLinear()
    .domain([0, d3.max(message.tables.DEFAULT.map(d => d.metric[0]))])
    .range([0, chartHeight]);

  // get the user-selected bar color
  let barColor = styleVal(message, "barColor");

  // add bars
  const bars = chartSvg
    .append("g")
    .attr("class", "bars")
    .selectAll("rect.bars")
    .data(message.tables.DEFAULT)
    .enter()
    .append("rect")
    .attr("x", d => xScale(d.dimension[0]))
    .attr("y", d => chartHeight - yScale(d.metric[0]))
    .attr("width", xScale.bandwidth())
    .attr("height", d => yScale(d.metric[0]))
    .attr("fill", barColor);

  // add text
  const text = svg
    .append("g")
    .selectAll("text")
    .data(message.tables.DEFAULT)
    .enter()
    .append("text")
    .attr(
      "x",
      d => xScale(d.dimension[0]) + xScale.bandwidth() / 2 + margin.left
    )
    .attr("y", height - margin.bottom / 4)
    .attr("text-anchor", "middle")
    .attr("fill", barColor)
    .text(d => d.dimension[0]);
};

// renders locally
if (LOCAL) {
  drawViz(local.message);
} else {
  dscc.subscribeToData(drawViz, {transform: dscc.objectTransform});
}

Save src/index.js, then go back to your local browser session. See it running locally, then again, change const LOCAL to false.

Upload your updated files to Google Cloud Storage by running:

npm run build:dev
npm run push:dev

Refresh your Data Studio report. You should be able to change the color of your bars now.

fd4e436a6e8dd58b.gif

13. Prod deployments

Prod deployments

Once you're happy with your visualization, make sure const LOCAL in src/index.js is false, then run.

npm run build:prod
npm run push:prod

This will deploy your files to your "prod" GCS bucket location. Additionally, caching will be enabled, and the bundled JavaScript will be appropriately minified.

Just like before, the location of your deployment will be printed in the console. Use this "manifest path" to load your "prod" visualization in a Data Studio report.

Congratulations! You've just built your first Community Visualization with the dscc-gen tool.

14. Next steps

Extend your visualization

Do more with Community Visualizations

Additional resources

Below are various resources you can access to help you dig deeper into the material covered in this codelab.

Resource Type

User Features

Developer Features

Documentation

Help Center

Developer Documentation

News & Updates

Sign up in Data Studio > User Settings

Developer Mailing List

Ask Questions

User Forum

Stack Overflow [google-data-studio]Data Studio Developers Forum

Videos

Data Studio on Youtube

Coming Soon!

Examples

Report Gallery

Open Source Repository