Inline Notations in Tableau


Inline Notations in Tableau

Tableau Dashboards are great for a lot of things; however, one need I hear often is the ability to add notations to dashboards. You can obviously add notations inside Tableau Desktop, but in an Enterprise level dashboard, there are many issues with this approach.

Any user annotating your dashboard would need access to edit the Tableau file. Sometimes (usually), these users are not as familiar with Tableau and may find this approach daunting. Even when users are properly trained on annotating the dashboards (and you are confident that they will not destroy anything), they will need to publish a new version of the dashboard every time a new annotation is needed. 

In enterprise environments, collaboration drives adoption. I’ve seen teams pull dashboards into PowerPoint and add notations there. Wouldn’t it be better (and simpler) to simply give these same teams tools to add notations inline? 

Luckily, with a little JavaScript API magic, there is another way to leave notations on dashboard points! Unlike traditional annotations, these notes come into the data as fields and can be formatted and customized as much as you’d like.

In our example, I’m using a simple comment box storing the comment on the month. Since this is web-based, you could add as much functionality as you’d like. For example, you could store the username of the commenter, a “category” to change colors in the tooltip or even something as simple as a “like”/”dislike.”

How It’s Done

I’ve attached the source code for this project to this post. Basically, at a high level, we used the JavaScript API to catch mark selections and then PHP to store the mark in a database accessible to Tableau. Feel free to dive into the code if you’d rather skip ahead!

In building out the setup, first we need a dashboard. I used Superstore as a base, but you could obviously use whatever data you want.

Next, I setup a table to hold our comments. For my table, I simply need a key to store the “Month” and a field for the “Comment” itself. If you wanted to store more information, such as a username, you could add an additional field to this table.

After completing the table, I created a new live connection in the Superstore-based workbook to the new comment table. Use a live connection here so that you get the latest comments as they are entered.

Now, let’s dive into the JavaScript side! To start, I created a hidden modal window waiting for the user to click a mark. I used the MARKS_SELECTION event to show this modal when the user clicks a mark:

 * Instantiate our vizualization.
$(function() {
	var url  = 'https://sampleServerUrl/views/SuperStoreSalesVProfit/SuperStoreSales';
	var vizOptions = {
		showTabs           : true,
		hideToolbar        : true,
		width              : "420px",
		height             : "420px"
	currentViz = new tableauSoftware.Viz(document.getElementById('viz'), url, vizOptions);
	currentViz.addEventListener(tableauSoftware.TableauEventName.MARKS_SELECTION, onMarkSelect);

 * Catches the tableau event fired when a filter is changed.
function onMarkSelect(e)
	e.getMarksAsync().then(function (marks) {
		for (var i = 0; i < marks.length; i++) {
			var pairs = marks[i].getPairs();
			for (var j = 0; j < pairs.length; j++) {
				if (pairs[j].fieldName == 'MONTH(Order Date)') {
					selectedMonth = pairs[j].formattedValue;

When the user clicks the save link, the comment data is passed through Ajax to a PHP script that saves the content to the database. When the Ajax call is complete, I used the JavaScript API to reset the marks and refresh the dashboard’s data. This allows the user to see their comment as soon as they post it.

 * Saves the annotation to the database
function saveAnnotation()
		url  : "add_comment.php",
		data : {
			'month'   : selectedMonth,
			'comment' : $('#notes').val()
	}).done(function() {
		var sheets = currentViz.getWorkbook().getActiveSheet().getWorksheets();
		for (var j = 0; j < sheets.length; j++) {

And there you have it – inline notations in Tableau without having to edit the Tableau file itself! This example is fairly simplistic, but it can easily be expanded to fit many different needs. Using the JavaScript API, customization is only limited by your imagination!

More About the Author

Derrick Austin

Curator Platform Lead
Five Years of Custom Embedded Analytics with Curator Thinking back, 2013 was an interesting year for many reasons. During the “International Year of Quinoa”, the world welcomed Prince ...
Curator by InterWorks Officially Turns 4 Curator is turning four years old! It’s awesome to be celebrating this milestone, but some of you may have just met Curator for the ...

See more from this author →

InterWorks uses cookies to allow us to better understand how the site is used. By continuing to use this site, you consent to this policy. Review Policy OK


Interworks GmbH
Ratinger Straße 9
40213 Düsseldorf
Geschäftsführer: Mel Stephenson

Telefon: +49 (0)211 5408 5301

Amtsgericht Düsseldorf HRB 79752
UstldNr: DE 313 353 072


Love our blog? You should see our emails. Sign up for our newsletter!