I am using d3.time.scale()
(reference here) to create time scale and providing tick values using axis.tickValues([values])
(here). The ticks are rendered for the specified Date objects provided in [values].
All fine, but the tick values representations are always in current time zone of the browser. Now comes the requirement to show it in a specific time zone (say, 'Asia/Calcutta'). Is there a way to achieve this? The max option I see is for formatting the ticks, but not replacing them with custom values, which doesn't help the case.
EDIT: This might be achieved using an external library like moment.js, but it is preferred if this could be avoided.
Based on the solution by Mark, here is a working solution without using external library. Enter the Time zone id (e.g. - Europe/Berlin) in the text field.
// Set the dimensions of the canvas / graph
var margin = {
top: 30,
right: 20,
bottom: 100,
left: 50
},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
var currentTZ = "local";
// Set the ranges
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
// Define the axes
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(10)
.tickFormat(function (d) {
if (currentTZ === "local") return d3.time.format('%X')(d);
else {
console.log(currentTZ);
return d3.time.format('%X')(new Date(d.toLocaleString('en-US', {
timeZone: currentTZ
})));
}
});
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
// Define the line
var valueline = d3.svg.line()
.x(function (d) {
return x(d.date);
})
.y(function (d) {
return y(d.close);
});
// Adds the svg canvas
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
var data = [{
date: new Date(0),
close: Math.random() * 100
}, {
date: new Date(1800000),
close: Math.random() * 100
}, {
date: new Date(3600000),
close: Math.random() * 100
}, {
date: new Date(5400000),
close: Math.random() * 100
}, {
date: new Date(7200000),
close: Math.random() * 100
}, {
date: new Date(9000000),
close: Math.random() * 100
}, {
date: new Date(10800000),
close: Math.random() * 100
}, {
date: new Date(12600000),
close: Math.random() * 100
}]
// Scale the range of the data
x.domain(d3.extent(data, function (d) {
return d.date;
}));
y.domain([0, d3.max(data, function (d) {
return d.close;
})]);
// Add the valueline path.
svg.append("path")
.attr("class", "line")
.attr("d", valueline(data));
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function (d) {
return "rotate(-65)"
});
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
handleClick = function () {
currentTZ = document.getElementById('timeZ').value;
console.log(currentTZ)
svg.selectAll("g.x.axis")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function () {
return "rotate(-65)"
});
};
body {
font: 12px Arial;
}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path, .axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<input name="Submit" type="submit" value="Change Time" onClick="handleClick()">
<input type="text" id="timeZ" value="local">
</form>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With