Toggle navigation
Home
▼ Details
Products and pricing
Chart gallery
User stories
Text analytics
CDC NAMCS Library
Blog
Tutorials
Contact
Sign in
Post Editor
← All help posts
View post
Save
Protobi is a lightweight library to visualize survey data in your browser. Protobi includes a number of standard chart types, but also allows you to create your own charts. So if you're familiar with web programming, this tutorial is for you. Protobi's API is open, and the example below shows how you how to extend it. And in any case we're happy to create custom widgets for your specific project and we have a growing library of general charts you can import and extend. ## Libraries included Protobi includes leading visualization libraries [d3.js](https://d3js.org/) and [Plotly.js](https://plot.ly/) as well as utility libs like [lodash.js](https://lodash.com/) , [Backbone.js](https://backbonejs.org/) and [jQuery](https://jquery.com/). You can include additional libs and stylesheets, as shown below. ## Example Here we'll create a new chart type that uses The Wall Street Journal's [Squaire](http://wsj.github.io/squaire/) algorithm to displays state data geographically as a pseudo-map with neat squares: <img src="/uploads/upload/image/5200/direct/1561571465160-squaire.png" alt="Protobi square tile map chart displaying survey question "S3 - In which state is your primary practice registered?" with all 50 US states arranged in a geographic grid layout, showing California with 21 responses." style="width: 360px;" class="fr-fic fr-dib"> The WSJ Squaire chart assumes an input variable with two-character state abbreviations. For this example we have a survey with a variable **s3** with exactly this: <img src="/uploads/upload/image/5200/direct/1561571478164-states.png" alt="Protobi interface showing a horizontal bar chart with a Filter input box and Apply button, displaying state response frequencies where [NA] leads with 63 responses, followed by CA with 21, NY with 14, and FL with 11 responses." style="width: 360px;" class="fr-fic fr-dib"> ## Define a minimal chart In the Admin tab of the project, create a new document called **squaire.js**. Then press "Edit/Run..." and paste the following code there and press "Save." This is the custom code that defines our new chart. The code below is boilerplate that extends Protobi's `BasicElement` to define a new `SquaireChart`. You don't really need to read it in great detail, just note that there are two methods that your code will override: - `preRender: function(callback) {}` - `render`: function() {}\` The method **preRender** is where you'll put background calculations or code should run asynchronously in the background before rendering. The method **render** is where you'll actually draw the visualization. Specifically, you'll render a DOM element referenced by `this.$content`. ## Boilerplate ``` $(function() { $(".protobi.app").on("protobi-loaded", function() { var BasicElement = protobi.widgetFactory.getView('BasicElement') var SquaireChart = BasicElement.extend({ alias: "Squaire", className: 'element resizable squaire', defaultOptions: {}, moreEvents: {}, resizable: true, showMargin: false, events: function () { var parentEvents = BasicElement.prototype.events if (_.isFunction(parentEvents)) { parentEvents = BasicElement.prototype.events(); } return _.extend({}, parentEvents, this.moreEvents); }, renderChildren: function () { return false }, postInitialize: function (args) { var self = this; SquaireChart.__super__.postInitialize.apply(this, arguments); this.listenTo(this.tabular, 'filter', self.update) this.listenTo(this.model, 'change', self.update) this.listenTo(this.viewModel, 'change:format', this.update) }, preRender: function (callback) { // ... add your calculation code here ... return callback(null, this.data) }, renderBody: function () { // ... add your rendering code here... this.$content.html("Hello World!!); return; } }) protobi.widgetFactory.registerView('SquaireChart', SquaireChart) }); }) ``` Protobi uses [Backbone.js](https://backbonejs.org/) to define charts. The above code extends the basic chart type to create a new one called "SquaireChart": ## Apply the new chart You can now apply this new chart type to any element. Create a new element. Select "Edit JSON..." and set `"chartType": "SquaireChart"`: <img src="/uploads/upload/image/5200/direct/1561571508885-new-chart.png" alt="Protobi "Edit element properties" dialog window displaying JSON code with three properties: "key": "chart1", "chartType": "Squaire" (highlighted on line 3), and "field": "s3", with Cancel and Ok buttons in the header." style="width: 360px;" class="fr-fic fr-dib"> Voilá, you now have a new chart that uses this code to render the element. This doesn't do anything special yet but it will... <img src="/uploads/upload/image/5200/direct/1561571521833-minimal.png" alt="Protobi chart element labeled "chart1" displaying a minimal custom chart implementation with the text "Edit..." followed by "Hello world!" in a dashed border container." style="width: 360px;" class="fr-fic fr-dib"> ## Define data prep Do any calculations in the method `preRender`. This method is called in the background before rendering any time the element or filters change. Here we'll just calculate the distribution of this element given its key and field attributes. Replace the method `preRender` as shown below: ``` preRender: function (callback) { "use strict"; var self = this; this.table = this.tabular.getDistribution(this.model, ['current']); return callback(null, this.data) }, ``` ## Include external libraries your code requires In the Admin tab of the project, create a new process called **header**. This will allow you to specify any additional resources your project requires. Then press "Edit/Run..." and paste the following code there and press "Save." At the top include any external library calls your method requires. Here we'll call the WSJ Squaire library directly from GitHub using jsDelivr: ``` <script type="text/javascript" src="https://app.protobi.com/v3/datasets/5c1804033e40da00044ff56f/direct/squaire.js"></script> <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/WSJ/squaire/src/js/squaire.js"></script> ``` In the example above replace `5c1804033e40da00044ff56f` with your project ID which can be found in the URL. ## Render the chart Replace the line `// ... add your rendering code here...` with code that draws the chart as you would like to see it. Add any content to a DOM element defined by the variable `this.$content`. In this example we'll adds two new `<div>` elements that Squaire expects, and then calls the Squaire library to render them: ## Example ``` renderBody: function () { "use strict"; var self = this; if (!self.table) return; self.$content.empty() var chartOptions = self.getChartOptions(); var showMissing = this.getShowMissing() var mapContainer = $("<div>") .addClass('map-container') .appendTo(this.$content) var tipContainer = $("<div>") .addClass('squaire-toolbox') .appendTo(this.$content) var data = {} this.table.getRowKeys().map(function (rowKey) { var freq = self.table.getFreq( 'current', rowKey, showMissing ) data[rowKey] = { "value": freq } }) var map = new Squaire(data, { colors: d3.scale .quantize() .domain([1, 5]) .range(['#c9e2f5', '#0098db']), el: mapContainer[0] }); return; } ``` ## Result We now have an interactive chart that displays frequencies by state as a stylized US map, and this chart type can be applied to multiple elements. <img src="/uploads/upload/image/5200/direct/1561571539299-squaire%20(1).png" alt="Protobi square tile map chart displaying survey question "S3 - In which state is your primary practice registered?" with all 50 US states arranged in a geographic grid layout, showing California with 21 responses." style="width: 360px;" class="fr-fic fr-dib"> ## Cheat If you want this specific chart in your project, you don't need to do all the steps above. You can include the following in your header code and include code we've already written. These will define two new chartType values, "Squaire" and "MapUSStates". Protobi has a growing library of advanced charts, and we're working on better ways to share these across projects. But for now just paste these into your header. ``` <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WSJ/squaire/dist/squaire.css"/> <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/WSJ/squaire/src/js/squaire.js"></script> <script type='text/javascript' src="https://app.protobi.com/v3/datasets/5c23a0bf28bd890004edb591/direct/d3-tip.js"></script> <script type='text/javascript' src="https://app.protobi.com/v3/datasets/5c23a0bf28bd890004edb591/direct/squaire.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/topojson/1.1.0/topojson.min.js"></script> <script type='text/javascript' src="https://app.protobi.com/v3/datasets/5c23a0bf28bd890004edb591/direct/map-us-states.js"></script> ``` ## Closing note If you're working your way through this tutorial, yay you! This is an advanced topic. You're welcome to contact us [support@protobi.com](mailto:support@protobi.com) and we'll help you get up to speed.
Publishing
Date
Status
Published
Draft
Slug
edit
Content
Thumbnail
Categories
Manage
New to Protobi?
Charts
Making Changes
Intermediate topics for editors
Frequently Asked Questions
SERMO Topics
Tutorial Pages
Internal Docs
Data Processing
Videos
Obsolete
GSG Admin
SERMO Admin
GSG Topics
How to...
Basics for viewers
Basics for editors
For project admins
Advanced topics
Assessments
Articles (in-progress)
New and updated articles
Process data in Protobi
superseded
Text open-end questions
Troubleshooting
Tracking studies
Organizing the view
API References
Tools
AI Database
Checking AI...
Convert to MD
Danger zone
Delete