|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<style> |
|
|
|
body { |
|
font: 10px sans-serif; |
|
} |
|
|
|
.axis path, |
|
.axis line { |
|
fill: none; |
|
stroke: #000; |
|
shape-rendering: crispEdges; |
|
} |
|
|
|
rect.pane { |
|
cursor: move; |
|
fill: none; |
|
pointer-events: all; |
|
} |
|
|
|
</style> |
|
<body> |
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
<script src="http://techanjs.org/techan.min.js"></script> |
|
<script> |
|
|
|
var margin = {top: 20, right: 20, bottom: 30, left: 50}, |
|
width = 960 - margin.left - margin.right, |
|
height = 500 - margin.top - margin.bottom; |
|
|
|
var parseDate = d3.time.format("%d-%b-%y%Z").parse; |
|
|
|
var parseIntradayDate = d3.time.format("%Y%m%d%H%M%Z").parse; |
|
|
|
var zoomTechan = d3.behavior.zoom() |
|
.on("zoom", draw); |
|
|
|
var zoomTechanNonClamped = d3.behavior.zoom(); |
|
|
|
var zoomTechanUtcNonClamped = d3.behavior.zoom(); |
|
|
|
var zoomX = d3.behavior.zoom(); |
|
|
|
var zoomXUtc = d3.behavior.zoom(); |
|
|
|
var zoomTechanIntraday = d3.behavior.zoom(); |
|
|
|
var zoomTechanIntradayNonClamped = d3.behavior.zoom(); |
|
|
|
var zoomTechanIntradayUtcNonClamped = d3.behavior.zoom(); |
|
|
|
var zoomXIntraday = d3.behavior.zoom(); |
|
|
|
var zoomXIntradayUtc = d3.behavior.zoom(); |
|
|
|
var x = d3.time.scale() |
|
.range([0, width]); |
|
|
|
var xUtc = d3.time.scale.utc() |
|
.range([0, width]); |
|
|
|
var xIntraday = d3.time.scale() |
|
.range([0, width]); |
|
|
|
var xIntradayUtc = d3.time.scale.utc() |
|
.range([0, width]); |
|
|
|
var techanTime = techan.scale.financetime() |
|
.range([0, width]); |
|
|
|
var techanTimeNonClamped = techan.scale.financetime() |
|
.range([0, width]); |
|
|
|
var techanTimeUtcNonClamped = techan.scale.financetime.utc() |
|
.range([0, width]); |
|
|
|
var techanIntradayTime = techan.scale.financetime() |
|
.range([0, width]); |
|
|
|
var techanIntradayTimeNonClamped = techan.scale.financetime() |
|
.range([0, width]); |
|
|
|
var techanIntradayUtcTimeNonClamped = techan.scale.financetime.utc() |
|
.range([0, width]); |
|
|
|
var xAxis = d3.svg.axis() |
|
.scale(x) |
|
.orient("bottom"); |
|
|
|
var xAxisUtc = d3.svg.axis() |
|
.scale(xUtc) |
|
.orient("bottom"); |
|
|
|
var xAxisIntraday = d3.svg.axis() |
|
.scale(xIntraday) |
|
.orient("bottom"); |
|
|
|
var xAxisIntradayUtc = d3.svg.axis() |
|
.scale(xIntradayUtc) |
|
.orient("bottom"); |
|
|
|
var xAxisTechan = d3.svg.axis() |
|
.scale(techanTime) |
|
.orient("bottom"); |
|
|
|
var xAxisTechanNonClamped = d3.svg.axis() |
|
.scale(techanTimeNonClamped) |
|
.orient("bottom"); |
|
|
|
var xAxisTechanUtcNonClamped = d3.svg.axis() |
|
.scale(techanTimeUtcNonClamped) |
|
.orient("bottom"); |
|
|
|
var xAxisTechanIntraday = d3.svg.axis() |
|
.scale(techanIntradayTime) |
|
.orient("bottom"); |
|
|
|
var xAxisTechanIntradayNonClamped = d3.svg.axis() |
|
.scale(techanIntradayTimeNonClamped) |
|
.orient("bottom"); |
|
|
|
var xAxisTechanIntradayUtcNonClamped = d3.svg.axis() |
|
.scale(techanIntradayUtcTimeNonClamped) |
|
.orient("bottom"); |
|
|
|
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 + ")"); |
|
|
|
svg.append("text") |
|
.attr("transform", "translate(0," + height*0.05 + ")") |
|
.attr("y", -6) |
|
.text("TechanJS Finance Time Intraday (clamped zoom)"); |
|
|
|
svg.append("g") |
|
.attr("class", "x axis techan intraday clamped") |
|
.attr("transform", "translate(0," + height*0.05 + ")"); |
|
|
|
svg.append("text") |
|
.attr("transform", "translate(0," + height*0.15 + ")") |
|
.attr("y", -6) |
|
.text("TechanJS Finance Time Intraday (non clamped zoom)"); |
|
|
|
svg.append("g") |
|
.attr("class", "x axis techan intraday nonclamped") |
|
.attr("transform", "translate(0," + height*0.15 + ")"); |
|
|
|
svg.append("text") |
|
.attr("transform", "translate(0," + height*0.25 + ")") |
|
.attr("y", -6) |
|
.text("TechanJS Finance Time Intraday UTC (non clamped zoom)"); |
|
|
|
svg.append("g") |
|
.attr("class", "x axis techan intraday-utc nonclamped") |
|
.attr("transform", "translate(0," + height*0.25 + ")"); |
|
|
|
svg.append("text") |
|
.attr("transform", "translate(0," + height*0.35 + ")") |
|
.attr("y", -6) |
|
.text("D3 Time Intraday"); |
|
|
|
svg.append("g") |
|
.attr("class", "x axis d3 intraday") |
|
.attr("transform", "translate(0," + height*0.35 + ")"); |
|
|
|
svg.append("text") |
|
.attr("transform", "translate(0," + height*0.45 + ")") |
|
.attr("y", -6) |
|
.text("D3 Time Intraday UTC"); |
|
|
|
svg.append("g") |
|
.attr("class", "x axis d3 intraday-utc") |
|
.attr("transform", "translate(0," + height*0.45 + ")"); |
|
|
|
svg.append("g") |
|
.attr("class", "x axis techan daily clamped") |
|
.attr("transform", "translate(0," + height*0.6 + ")"); |
|
|
|
svg.append("text") |
|
.attr("transform", "translate(0," + height*0.6 + ")") |
|
.attr("y", -6) |
|
.text("TechanJS Finance Time Daily (clamped zoom)"); |
|
|
|
svg.append("g") |
|
.attr("class", "x axis techan daily nonclamped") |
|
.attr("transform", "translate(0," + height*0.7 + ")"); |
|
|
|
svg.append("text") |
|
.attr("transform", "translate(0," + height*0.7 + ")") |
|
.attr("y", -6) |
|
.text("TechanJS Finance Time Daily (non clamped zoom)"); |
|
|
|
svg.append("g") |
|
.attr("class", "x axis techan daily-utc nonclamped") |
|
.attr("transform", "translate(0," + height*0.8 + ")"); |
|
|
|
svg.append("text") |
|
.attr("transform", "translate(0," + height*0.8 + ")") |
|
.attr("y", -6) |
|
.text("TechanJS Finance Time Daily UTC (non clamped zoom)"); |
|
|
|
svg.append("g") |
|
.attr("class", "x axis d3 daily") |
|
.attr("transform", "translate(0," + height*0.9 + ")"); |
|
|
|
svg.append("text") |
|
.attr("transform", "translate(0," + height*0.9 + ")") |
|
.attr("y", -6) |
|
.text("D3 Time Daily"); |
|
|
|
svg.append("g") |
|
.attr("class", "x axis d3 daily-utc") |
|
.attr("transform", "translate(0," + height + ")"); |
|
|
|
svg.append("text") |
|
.attr("transform", "translate(0," + height + ")") |
|
.attr("y", -6) |
|
.text("D3 Time Daily UTC"); |
|
|
|
svg.append("rect") |
|
.attr("class", "pane") |
|
.attr("width", width) |
|
.attr("height", height) |
|
.call(zoomTechan); |
|
|
|
d3.csv("data.csv", function(error, data) { |
|
var accessor = techan.accessor.ohlc(); |
|
|
|
data = data.map(function(d) { |
|
return { |
|
date: parseDate(d.Date+"+0000"), |
|
open: +d.Open, |
|
high: +d.High, |
|
low: +d.Low, |
|
close: +d.Close, |
|
volume: +d.Volume |
|
}; |
|
}).sort(function(a, b) { return d3.ascending(accessor.d(a), accessor.d(b)); }); |
|
|
|
x.domain(d3.extent(data.map(accessor.d))); |
|
xUtc.domain(d3.extent(data.map(accessor.d))); |
|
techanTime.domain(data.map(accessor.d)); |
|
techanTimeNonClamped.domain(data.map(accessor.d)); |
|
techanTimeUtcNonClamped.domain(data.map(accessor.d)); |
|
zoomTechan.x(techanTime.zoomable()); |
|
zoomTechanNonClamped.x(techanTimeNonClamped.zoomable().clamp(false)); |
|
zoomTechanUtcNonClamped.x(techanTimeUtcNonClamped.zoomable().clamp(false)); |
|
zoomX.x(x); |
|
zoomXUtc.x(xUtc); |
|
draw(); // Could this ever clash with the other data load? |
|
}); |
|
|
|
d3.csv("intraday-data.csv", function(error, data) { |
|
var accessor = techan.accessor.ohlc(); |
|
|
|
data = data.map(function(d) { |
|
return { |
|
date: parseIntradayDate(d.Date+"+0000"), // Force 0 timezone offset. Time rendered should always be between 9pm-3am. |
|
open: +d.Open, |
|
high: +d.High, |
|
low: +d.Low, |
|
close: +d.Close |
|
}; |
|
}).sort(function(a, b) { return d3.ascending(accessor.d(a), accessor.d(b)); }); |
|
|
|
xIntraday.domain(d3.extent(data.map(accessor.d))); |
|
xIntradayUtc.domain(d3.extent(data.map(accessor.d))); |
|
techanIntradayTime.domain(data.map(accessor.d)); |
|
techanIntradayTimeNonClamped.domain(data.map(accessor.d)); |
|
techanIntradayUtcTimeNonClamped.domain(data.map(accessor.d)); |
|
zoomTechanIntraday.x(techanIntradayTime.zoomable()); |
|
zoomTechanIntradayNonClamped.x(techanIntradayTimeNonClamped.zoomable().clamp(false)); |
|
zoomTechanIntradayUtcNonClamped.x(techanIntradayUtcTimeNonClamped.zoomable().clamp(false)); |
|
zoomXIntraday.x(xIntraday); |
|
zoomXIntradayUtc.x(xIntradayUtc); |
|
draw(); // Could this ever clash with the other data load? |
|
}); |
|
|
|
function draw() { |
|
zoomX.translate(zoomTechan.translate()); |
|
zoomX.scale(zoomTechan.scale()); |
|
|
|
zoomXUtc.translate(zoomTechan.translate()); |
|
zoomXUtc.scale(zoomTechan.scale()); |
|
|
|
zoomTechanNonClamped.translate(zoomTechan.translate()); |
|
zoomTechanNonClamped.scale(zoomTechan.scale()); |
|
|
|
zoomTechanUtcNonClamped.translate(zoomTechan.translate()); |
|
zoomTechanUtcNonClamped.scale(zoomTechan.scale()); |
|
|
|
zoomXIntraday.translate(zoomTechan.translate()); |
|
zoomXIntraday.scale(zoomTechan.scale()); |
|
|
|
zoomXIntradayUtc.translate(zoomTechan.translate()); |
|
zoomXIntradayUtc.scale(zoomTechan.scale()); |
|
|
|
zoomTechanIntraday.translate(zoomTechan.translate()); |
|
zoomTechanIntraday.scale(zoomTechan.scale()); |
|
|
|
zoomTechanIntradayNonClamped.translate(zoomTechan.translate()); |
|
zoomTechanIntradayNonClamped.scale(zoomTechan.scale()); |
|
|
|
zoomTechanIntradayUtcNonClamped.translate(zoomTechan.translate()); |
|
zoomTechanIntradayUtcNonClamped.scale(zoomTechan.scale()); |
|
|
|
svg.select("g.x.axis.d3.daily").call(xAxis); |
|
svg.select("g.x.axis.d3.daily-utc").call(xAxisUtc); |
|
svg.select("g.x.axis.techan.daily.clamped").call(xAxisTechan); |
|
svg.select("g.x.axis.techan.daily.nonclamped").call(xAxisTechanNonClamped); |
|
svg.select("g.x.axis.techan.daily-utc.nonclamped").call(xAxisTechanUtcNonClamped); |
|
svg.select("g.x.axis.d3.intraday").call(xAxisIntraday); |
|
svg.select("g.x.axis.d3.intraday-utc").call(xAxisIntradayUtc); |
|
svg.select("g.x.axis.techan.intraday.clamped").call(xAxisTechanIntraday); |
|
svg.select("g.x.axis.techan.intraday.nonclamped").call(xAxisTechanIntradayNonClamped); |
|
svg.select("g.x.axis.techan.intraday-utc.nonclamped").call(xAxisTechanIntradayUtcNonClamped); |
|
} |
|
|
|
</script> |
Can we get a sample showing hourly time?
My data is the following "2-May-15 13:45:00"
Thanks much appreciated