I have a combo chart with a bar showing the average number of seconds per week for a reaction time. I want to display the value as HH:MM:SS or MM:SS instead of just the number of seconds above the bar. In the example, the last value of 849 seconds should display as 00:14:09. Ideally, if the time was less than 1 hour, then just display 14:09
JavaScript
google.charts.load('current', { packages: ['corechart'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
var jsonList = @(Json.Serialize(Model.listWeeklyWebLeadReactionTime))
var title = 'Weekly Web Lead Reaction Time';
data.addColumn('string', 'Week Of');
data.addColumn('number', 'Avg Reaction Time');
data.addColumn('number', 'Reaction Goal');
data.addColumn('number', '% Change');
data.addRows(jsonList.map((p) => {
return [p.weekOf, p.avgReactionTime, p.reactionTimeGoal, p.reactionPercentChange];
}));
var toHHMMSS = (secs) => {
var sec_num = parseInt(secs, 10)
var hours = Math.floor(sec_num / 3600)
var minutes = Math.floor(sec_num / 60) % 60
var seconds = sec_num % 60
return [hours, minutes, seconds]
.map(v => v < 10 ? "0" + v : v)
.filter((v, i) => v !== "00" || i > 0)
.join(":")
}
var formatPercent = new google.visualization.NumberFormat({ pattern: '#.#%' });
formatPercent.format(data, 3);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
},
2,
{
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotationText"
},
3,
{
calc: "stringify",
sourceColumn: 3,
type: "string",
role: "annotation"
}
]);
var options = {
interpolateNulls: true,
title: title,
titlePosition: 'out',
isStacked: false,
seriesType: "bars",
vAxes: {
0: {
textPosition: 'out',
viewWindowMode: 'pretty',
title: "",
viewWindow: { min: -5000, max: 5000 },
gridlines: { color: 'lightgray' }
},
1: {
textPosition: 'out',
viewWindow: { min: -1, max: 1 },
format: 'percent',
gridlines: { color: 'transparent' }
},
},
series: {
0: {
targetAxisIndex: 0,
color: 'lightgray',
annotations: {
alwaysOutside: true,
stem: {
color: 'gray',
length: 8
},
textStyle: {
color: 'gray',
fontSize: 11,
bold: false
},
}
},
1: {
targetAxisIndex: 0,
color: 'purple',
type: 'line',
lineWidth: 1,
lineDashStyle: [4, 4],
pointSize: 0,
highContrast: true,
annotations: {
stem: {
color: 'transparent',
length: -30
},
textStyle: {
color: 'purple',
fontSize: 11,
bold: false,
format: '#,###'
},
}
},
2: {
targetAxisIndex: 1,
color: 'red',
type: 'line',
lineWidth: 1,
lineDashStyle: [4, 4],
pointSize: 5,
highContrast: true,
annotations: {
stem: {
color: 'red',
length: 10
},
textStyle: {
color: 'red',
fontSize: 11,
bold: false,
format: '#%'
},
}
}
},
width: '100%',
height: '450',
legend: { position: 'top' },
chartArea: {
height: '100%',
width: '100%',
top: 48,
left: 60,
right: 60,
bottom: 75
},
}
var chart = new google.visualization.ComboChart(document.getElementById('WeeklyWebLeadReactionTime'));
chart.draw(view, options);
I tried converting the seconds to a format of HH:MM:SS using this code that I found on the site, but I can't figure out how to implement it correctly.
var toHHMMSS = (secs) => {
var sec_num = parseInt(secs, 10)
var hours = Math.floor(sec_num / 3600)
var minutes = Math.floor(sec_num / 60) % 60
var seconds = sec_num % 60
return [hours, minutes, seconds]
.map(v => v < 10 ? "0" + v : v)
.filter((v, i) => v !== "00" || i > 0)
.join(":")
}
From the documentation, it guides to display the formatted value
getValue(rowIndex, columnIndex)
function.var getFormattedReactionTime = (column, dataTable, row) => {
return toHHMMSS(dataTable.getValue(row, column));
};
calc
property with the column index of avgReactionTime
value.view.setColumns([
0,
1,
{
calc: getFormattedReactionTime.bind(undefined, 1),
sourceColumn: 1,
type: 'string',
role: 'annotation',
},
...
]);