Skip to content

Instantly share code, notes, and snippets.

@valex
Created June 21, 2019 20:51
Show Gist options
  • Save valex/a322814bf0a9927b29eb3b2d62e6f2e1 to your computer and use it in GitHub Desktop.
Save valex/a322814bf0a9927b29eb3b2d62e6f2e1 to your computer and use it in GitHub Desktop.
d3.js v5 Multiformat for datetime scale
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>d3.js v5 Multiformat Date axis</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.2/d3.min.js"></script>
<link rel="stylesheet" href="style.css" >
</head>
<body>
<div id="d3_chart"></div>
<script src="scripts.js"></script>
<script type="text/javascript">
function autorun()
{
D3_CHART.init();
}
if (document.addEventListener) document.addEventListener("DOMContentLoaded", autorun, false);
else if (document.attachEvent) document.attachEvent("onreadystatechange", autorun);
else window.onload = autorun;
</script>
</body>
</html>
var D3_CHART = {
selector: '#d3_chart',
data:null,
svg: null,
mainGroup: null,
scaleX: null,
options:{
width: 640,
height: 480,
margins: {
top: 20,
right: 40,
bottom: 20,
left: 40,
},
},
redraw: function(){
this.init();
this.draw();
},
init: function(){
var el = d3.select(this.selector);
if(el.empty()){
console.warn('init(): Element for "'+this.selector+'" selector not found');
return;
}
console.log(d3.version);
this.scaleX = d3.scaleTime().rangeRound([0, this.options.width - this.options.margins.left - this.options.margins.right]);
this.svg = el
.append("svg")
.attr('xmlns', 'http://www.w3.org/2000/svg')
.attr("width", this.options.width)
.attr("height", this.options.height);
this.mainGroup = this.svg.append('g')
.attr('transform', 'translate(' + this.options.margins.left + ',' + this.options.margins.top + ')');
var periods = [
{
'text': 'Seconds',
'from': new Date('2019-06-21T08:58:55'),
'to': new Date('2019-06-21T08:59:06')
},
{
'text': 'Minutes',
'from': new Date('2019-06-21T08:55:00'),
'to': new Date('2019-06-21T09:06:00')
},
{
'text': 'Hours',
'from': new Date('2019-06-21T09:00:00'),
'to': new Date('2019-06-21T14:00:00')
},
{
'text': 'Days',
'from': new Date('2019-06-24T09:00:00'),
'to': new Date('2019-07-04T09:00:00')
},
{
'text': 'Months',
'from': new Date('2019-06-24T09:00:00'),
'to': new Date('2020-04-24T09:00:00')
},
{
'text': 'Years',
'from': new Date('2009-06-24T09:00:00'),
'to': new Date('2020-04-24T09:00:00')
}
];
for(var i=0; i < periods.length; i++){
// seconds
var xMin = periods[i]['from'];
var xMax = periods[i]['to'];
this.scaleX.domain([xMin, xMax]);
var yText = (this.options.height - (1 - i*0.2)*this.options.height);
var yScale = yText + 20;
this.mainGroup.append("g")
.attr("class", "axis x")
.attr("transform", "translate(0," + yScale + ")")
.call(d3.axisBottom(this.scaleX).ticks(8).tickFormat(this.multiFormat));
this.mainGroup.append("text")
.attr("x", 25)
.attr("y", yText)
.attr("dy", ".35em")
.text(periods[i]['text']);
}
},
clearChart: function(){
var el = d3.select(this.selector);
if(el.empty()){
console.warn('clearChart(): Element for "'+this.selector+'" selector not found');
return;
}
// clear element
el.html("");
},
multiFormat: function (date) {
// Establish the desired formatting options using locale.format():
// https://github.com/d3/d3-time-format/blob/master/README.md#locale_format
var formatMillisecond = d3.timeFormat(".%L"),
formatSecond = d3.timeFormat(":%S"),
formatMinute = d3.timeFormat("%I:%M"),
formatHour = d3.timeFormat("%I:%M %p"),
formatDay = d3.timeFormat("%a %d"),
formatWeek = d3.timeFormat("%b %d"),
formatMonth = d3.timeFormat("%B"),
formatYear = d3.timeFormat("%Y");
return (d3.timeSecond(date) < date ? formatMillisecond
: d3.timeMinute(date) < date ? formatSecond
: d3.timeHour(date) < date ? formatMinute
: d3.timeDay(date) < date ? formatHour
: d3.timeMonth(date) < date ? (d3.timeWeek(date) < date ? formatDay : formatWeek)
: d3.timeYear(date) < date ? formatMonth
: formatYear)(date);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment