Skip to main content

Table with tiny bar charts

The code for this example can be used in the Markdown visualization to create a styled table with a small bar chart in each row of. A row in the markdown table corresponds to a row in the results.

Setup

These charts use the Mustache iterator syntax to draw a chart for each row in the results. Your query should have a column for each bar that you want to display and then a calculation column for each bar that determines the height of each bar. The calculation in this example calculates the bar height as a percentage of the total for all the traffic sources. Adjust your calculation as needed for different analyses, but make sure you use the % formatting on the calculation column.

The following table explains each field used in the example, including the calculation formulas.

ColNameDescription or formulaPurpose
AState Groupsquery fieldused to make cute little badges in each row
BStatequery fieldmain label for the row
CEvents Countquery fieldTotal events used in table for displaying and to calculate denominator for bar height
DAdwordsquery fieldBlue bar
EAdwords % (calc_7)=D1 / C1% fill for blue bar (make sure to format as %)
FAdwordsquery fieldYellow bar
GAdwords % (calc_8)=F1 / C1% fill for yellow bar (make sure to format as %)
HAdwordsquery fieldPink bar
IAdwords % (calc_9)=H1 / C1% fill for pink bar (make sure to format as %)
JAdwordsquery fieldTeal bar
KAdwords % (calc_10)=J1 / C1% fill for teal bar (make sure to format as %)
LAdwordsquery fieldOrange bar
MAdwords % (calc_11)=L1 / C1% fill for orange bar (make sure to format as %)

Example code

<style>
<style>
article.fancy-table {
--color-adwords: 41,139,229;
--color-email: 247,181,78;
--color-facebook: 255,98,145;
--color-organic: 29,185,185;
--color-youtube: 255,133,21;
--bar-height: 40px;
--color-source: 0,0,0;
--color-opacity: 0.1;
--color-west: 80,144,70;
--color-south: 79,89,218;
--color-midwest: 210,66,58;
--color-northeast: 176,76,186;

& .adwords { --color-source: var(--color-adwords);}
& .email { --color-source: var(--color-email);}
& .facebook { --color-source: var(--color-facebook);}
& .organic { --color-source: var(--color-organic);}
& .youtube { --color-source: var(--color-youtube);}

& .west { --color-tag: var(--color-west); }
& .south { --color-tag: var(--color-south); }
& .midwest { --color-tag: var(--color-midwest); }
& .northeast { --color-tag: var(--color-northeast); }

& ul {
list-style: none;
margin: 0;
padding: 0;

& li {
padding: 0;
margin: 0;
}
}
}
article.fancy-table ul.source-legend {
display: flex;
flex-direction: row;
gap: 16px;
padding: 0 0 8px 12px;

& li {
display: flex;
flex-direction: row;
gap: 4px;
align-items: center;
color: var(--color-text1);
font-size: var(--font-xs);

& span {
display: block;
width: 12px;
height: 12px;
background-color: rgb(var(--color-source));
}
}
}
article.fancy-table table {
width: 100%;
border-collapse: collapse;

& thead { display: none;}
& th { white-space: nowrap; }
& td {
padding-block: 12px;
padding-inline: 12px;
border-bottom: 1px dotted var(--color-border2);
vertical-align: bottom;
}
& td.metrics,
& th.metrics {
text-align: right;
}
& td.metrics {
font-size: var(--font-md);
}
& td.summary ul {
display: flex;
flex-direction: column;
gap: 8px;
justify-content: center;

& .type span {
display: inline-block;
background: rgba(var(--color-tag),0.1);
padding: 0px 2px;
border-radius: 3px;
font-size: var(--font-xxs);
text-transform: uppercase;
color: rgb(var(--color-tag));
}
& .title {
color: var(--color-text4);
font-size: var(--font-md);
}
}
& td.sources ul {
display: flex;
flex-direction: row;
height: var(--bar-height);
gap: 2px;
justify-content: center;

& li {
width: 8px;
height: 100%;
background-color: rgba(var(--color-source), var(--color-opacity));
border-radius: 2px 2px 0 0;
display: flex;
flex-direction: column-reverse;
position: relative;
--tooltip-width: 100px;
--tooltip-height: 36px;
--translate-tip: calc(-1 * var(--tooltip-width));

& span.bar {
display: block;
width: 100%;
height: 1%;
border-radius: 2px 2px 0 0;
background-color: rgb(var(--color-source));
}
& span.tooltip-content {
visibility: hidden;
opacity: 0;
position: absolute;
z-index: 1;
bottom: 100%;
left: calc(0% - 8px);
top: calc(50% - var(--bar-height) / 2);
transform: translateX(var(--translate-tip));
height: var(--tooltip-height);
width: var(--tooltip-width);
background-color: #333;
color: white;
text-align: center;
border-radius: 5px;
padding: 4px 6px;
font-size: 10px;
font-weight: normal;
transition: opacity 0.15s;
box-shadow: -2px 2px 8px rgba(0,0,0,0.2);
line-height: 1.4;
word-wrap: break-word;
white-space: normal;
border-left: 8px solid rgb(var(--color-source));
}
& span.tooltip-content::after {
content: "";
position: absolute;
top: Calc(50% - 5px);
right: -5px;
margin-right: -5px;
border-width: 5px;
border-style: solid;
border-color: #333 transparent transparent transparent;
transform: rotate(-90deg);
}
}
& li:hover .tooltip-content {
visibility: visible;
opacity: 1;
}
}
}
</style>

<article class="fancy-table">
<ul class="source-legend">
<li class="adwords"><span></span>Adwords</li>
<li class="email"><span></span>Email</li>
<li class="facebook"><span></span>Facebook</li>
<li class="organic"><span></span>Organic</li>
<li class="youtube"><span></span>YouTube</li>
</ul>
<table>
<thead>
<tr>
<th class="summary">Article</th>
<th class="metrics">Total Views</th>
<th class="sources">Source</th>
</tr>
</thead>
<tbody>
{{#result}}
<tr>
<td class="summary">
<ul>
<li class="type {{events.state_groups.raw}}"><span>{{events.state_groups.value}}</span></li>
<li class="title">{{events.state.value}}</li>
</ul>
</td>
<td class="metrics">{{events.count.value}}</td>
<td class="sources">
<ul>
<li class="adwords">
<span class="bar" style="height: {{calc_7.value_static}}"></span>
<span class="tooltip-content">
{{fields.events.count_adwords.label}}<br />
{{events.count_adwords.value}} • {{calc_7.value_static}}</span>
</li>
<li class="email">
<span class="bar" style="height: {{calc_8.value_static}}"></span>
<span class="tooltip-content">
{{fields.events.count_email.label}}<br />
{{events.count_email.value}} • {{calc_8.value_static}}</span>
</li>
<li class="facebook">
<span class="bar" style="height: {{calc_9.value_static}}"></span>
<span class="tooltip-content">
{{fields.events.count_adwords.label}}<br />
{{events.count_adwords.value}} • {{calc_9.value_static}}</span>
</li>
<li class="organic">
<span class="bar" style="height: {{calc_10.value_static}}"></span>
<span class="tooltip-content">
{{fields.events.count_organic.label}}<br />
{{events.count_organic.value}} • {{calc_10.value_static}}</span>
</li>
<li class="youtube">
<span class="bar"style="height: {{calc_11.value_static}}"></span>
<span class="tooltip-content">
{{fields.events.count_you_tube.label}}<br />
{{events.count_you_tube.value}} • {{calc_11.value_static}}</span>
</li>
</ul>
</td>
</tr>
{{/result}}
</tbody>
</table>
</article>