Last active
February 27, 2019 22:48
-
-
Save josecanciani/9ba6f7a8a0577cbd09ceaa87b18247d5 to your computer and use it in GitHub Desktop.
It takes a -kibana for example- CSV file and creates an HTML page with a time chart. See usage in first comment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/php | |
<?php | |
$file = fopen('php://stdin', 'r'); | |
$stdout = fopen('php://stdin', 'r'); | |
$lineNumber = 0; | |
$code = new Code(); | |
while (!feof($file) && ($line = fgetcsv($file)) !== false) { | |
if ($lineNumber) { // ignore header | |
$logTime = strtotime($line[0]); | |
$startTime = $logTime - (float) $line[2]; | |
$code->add($line[1], $startTime, $logTime); | |
} | |
$lineNumber++; | |
} | |
fclose($file); | |
echo $code->get(); | |
class Code { | |
private $data = []; | |
private $categories = []; | |
private $colors = ['#3366CC', '#DC3912', '#FF9900', '#109618', '#990099', '#3B3EAC', '#0099C6', '#DD4477', '#66AA00', '#B82E2E', '#316395', '#994499', '#22AA99', '#AAAA11', '#6633CC', '#E67300', '#8B0707', '#329262', '#5574A6']; | |
private $categoryColors = []; | |
function add(string $category, float $start, float $end) { | |
$this->categories[] = $category; | |
$this->data[] = [$start, $end]; | |
} | |
function get() { | |
$this->buildColors(); | |
return str_replace( | |
['{$categories}', '{$data}', '{$height}'], | |
[json_encode($this->categories), $this->getEncodedData(), max(count($this->categories) * 20, 600)], | |
$this->src | |
); | |
} | |
private function buildColors() { | |
$categories = array_unique($this->categories); | |
foreach ($categories as $idx => $category) { | |
if ($idx < count($this->colors)) { | |
$this->categoryColors[$category] = $this->colors[$idx]; | |
} else { | |
$this->categoryColors[$category] = '#000000'; | |
} | |
} | |
} | |
private function getEncodedData() { | |
$data = '['; | |
foreach ($this->data as $idx => $row) { | |
$data .= ($idx ? ', ' : '') . '{low: ' . ($row[0] * 1000) . ', high: ' . ($row[1] * 1000) . ', color: "' . $this->categoryColors[$this->categories[$idx]] . '"}'; | |
} | |
$data .= ']' . PHP_EOL; | |
return $data; | |
} | |
private $src = " | |
<html> | |
<head> | |
<script src='https://code.highcharts.com/highcharts.js'></script> | |
<script src='https://code.highcharts.com/highcharts-more.js'></script> | |
<script src='https://code.highcharts.com/modules/exporting.js'></script> | |
<script src='https://code.highcharts.com/modules/export-data.js'></script> | |
<script> | |
Number.prototype.padLeft = function (n, str) { | |
var len = String(this).length; | |
return (len < n ? Array(n - len + 1).join(str || '0') : '') + this; | |
}; | |
Date.prototype.formatForTooltip = function () { | |
return this.getFullYear().padLeft(4) + '-' + (this.getMonth() + 1).padLeft(2) + '-' + this.getDate().padLeft(2) + ' ' + | |
this.getHours().padLeft(2) + ':' + this.getMinutes().padLeft(2) + ':' + this.getSeconds().padLeft(2) + '.' + this.getMilliseconds().padLeft(3) | |
; | |
}; | |
window.addEventListener('load', function() { | |
Highcharts.chart('container', { | |
chart: { | |
type: 'columnrange', | |
inverted: true, | |
height: {\$height} | |
}, | |
title: { | |
text: '' | |
}, | |
plotOptions: { | |
series: { | |
pointPadding: 0.1, | |
groupPadding: 0, | |
borderWidth: 0, | |
shadow: false, | |
animation: false | |
}, | |
columnrange: { | |
dataLabels: { | |
formatter: function () { | |
var low = this.point.low; | |
var high = this.point.high; | |
return this.y === low ? '' : ((high - low)/1000) + 's'; | |
}, | |
enabled: true | |
} | |
} | |
}, | |
yAxis: { | |
labels: { | |
enabled: false | |
}, | |
type: 'datetime' | |
}, | |
xAxis: { | |
labels: { | |
enabled: false | |
}, | |
categories: {\$categories} | |
}, | |
legend: { | |
enabled: false | |
}, | |
tooltip: { | |
formatter: function() { | |
var low = new Date(this.points[0].point.low); | |
var high = new Date(this.points[0].point.high); | |
return '<b>'+ this.x +'</b><br/>' + '<p style=\"font-family: monospace; font-size: 12px;\">' + low.formatForTooltip() + '</p><br/><p style=\"font-family: monospace; font-size: 12px;\">' + high.formatForTooltip() + '</p><br/>Elapsed time: <b>' + ((high - low)/1000) + '</b> secs'; | |
}, | |
shared: true | |
}, | |
series: [{ | |
name: 'Call time', | |
data: {\$data} | |
}] | |
}); | |
}); | |
</script> | |
</head> | |
<body> | |
<div id='container'></div> | |
</body> | |
</html> | |
"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage:
cat kibanaExport.csv | kibanaToTimeTable.php > chart.html; firefox chart.html
The csv file must have at least three columns with this order:
The chart will show horizontal bars starting in (logTime-elapsedTime) and ending in (logTime), so you can see what overlaps.
Sample output: