|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<script src="http://coffeescript.org/v1/browser-compiler/coffee-script.js"></script> |
|
<style> |
|
.chart { |
|
margin: 0 auto; |
|
width: 960px; |
|
min-height: 8px; |
|
height: 100%; |
|
box-shadow: 0 0 3px 1px #eee; |
|
} |
|
svg { |
|
vertical-align: top; |
|
width: 100%; |
|
height: 100%; |
|
} |
|
.tooltip { |
|
position: absolute; |
|
} |
|
.axis { |
|
height: 20px; |
|
} |
|
.zoom { |
|
cursor: move; |
|
position: absolute; |
|
top: 0; |
|
left: 0; |
|
fill: none; |
|
pointer-events: all; |
|
} |
|
</style> |
|
</head> |
|
|
|
<body> |
|
<div class="chart"></div> |
|
<script src="data.js"></script> |
|
<script type="text/coffeescript"> |
|
wrapper = document.querySelector '.chart' |
|
width = wrapper.clientWidth; |
|
parser = d3.isoParse |
|
|
|
minX = d3.min(VEHICLES, (d) -> parser d.start) |
|
maxX = d3.max(VEHICLES, (d) -> parser d.end) |
|
|
|
# --- X scale |
|
x = d3.scaleTime() |
|
.domain([minX, maxX]) |
|
.rangeRound([0, width]) |
|
|
|
# --- nest all the data |
|
symbols = d3.nest() |
|
.key (d) -> d.tir |
|
.entries(VEHICLES) |
|
|
|
height = wrapper.getBoundingClientRect().bottom |
|
|
|
spanX = (d) -> x(parser(d.start)) |
|
spanW = (d) -> x(parser(d.end)) - x(parser(d.start)) |
|
|
|
chart = (symbol) -> |
|
svg = d3.select this |
|
|
|
svg.selectAll 'rect' |
|
.data(symbol.values) |
|
.enter() |
|
.append 'rect' |
|
.attr 'x', (d) -> spanX d |
|
.attr 'y', 0 |
|
.attr 'width', (d) -> spanW d |
|
.attr 'height', height |
|
.attr 'fill', (d) -> d.color or '#ddf' |
|
.on 'mouseover', (d) -> |
|
tooltip.html [d.tir, d.start, d.end].join('<br>') |
|
.on 'mouseout', () -> |
|
tooltip.html '' |
|
|
|
# --- add all charts |
|
allCharts = d3.select(wrapper).selectAll('svg') |
|
.data(symbols) |
|
.enter() |
|
.append('svg') |
|
.attr('height', height) |
|
.each(chart) |
|
|
|
# --- add X axis |
|
xAxis = d3.axisBottom(x) |
|
.ticks(width / 100) |
|
|
|
globalX = d3.select(wrapper) |
|
.append('svg') |
|
.attr('class', 'axis') |
|
.call(xAxis) |
|
|
|
# --- catch all zoom svg rect |
|
catchAll = d3.select('body') |
|
.append 'svg' |
|
.attr 'class', 'zoom' |
|
.append 'rect' |
|
.attr 'fill', 'none' |
|
.attr 'width', width |
|
.attr 'height', wrapper.getBoundingClientRect().bottom |
|
|
|
# --- add tooltip |
|
tooltip = d3.select(wrapper).append('div') |
|
.attr 'class', 'tooltip' |
|
|
|
catchAll.call(d3.zoom() |
|
.scaleExtent([0.1, 10]) |
|
.on "zoom", -> |
|
transform = d3.event.transform |
|
globalX.call xAxis.scale(transform.rescaleX(x)) |
|
allCharts.selectAll('rect') |
|
.attr 'x', (d) -> transform.applyX spanX d |
|
.attr 'width', (d) -> transform.k * spanW d |
|
) |
|
</script> |
|
</body> |