[
  {
    "path": ".gitignore",
    "content": ".DS_Store\nbuild/\nnode_modules\nnpm-debug.log\n*.swp\n"
  },
  {
    "path": ".npmignore",
    "content": "build/*.zip\ntest/\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright 2017, Denise Mauldin\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the author nor the names of contributors may be used to\n  endorse or promote products derived from this software without specific prior\n  written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "README.md",
    "content": "# d3-timeline\n\nA d3 v4 version of d3-timeline \n\nGet something that looks like\n\n![Rectangular Timeline](examples/timeline1.png)\n\nfor a dataset that looks like\n\n```js\nvar testData = [\n\t{label: \"person a\", times: [\n\t\t{\"starting_time\": 1355752800000, \"ending_time\": 1355759900000},\n\t\t{\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n\t{label: \"person b\", times: [\n\t\t{\"starting_time\": 1355759910000, \"ending_time\": 1355761900000}]},\n\t{label: \"person c\", times: [\n\t\t{\"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n\t];\n```\n\nwith a call that looks like\n\n```js\nvar chart = d3.timelines();\n\nvar svg = d3.select(\"#timeline1\").append(\"svg\").attr(\"width\", 500)\n\t.datum(testData).call(chart);\n```\n\nWorks with circles. In case the rectangular edges are too pointy.\n\n![Circular Timeline](examples/timeline2.png)\n\nCombine rectangles and circles to your liking\n\n![Rectangular and Circular Timeline](examples/timeline3.png)\n\nby adding a ``display`` key to the data:\n\n```js\nvar rectAndCircleTestData = [\n\t\t{times: [{\"starting_time\": 1355752800000, \"display\": \"circle\"},\n\t\t\t\t\t\t {\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n\t\t{times: [{\"starting_time\": 1355759910000, \"display\":\"circle\"}, ]},\n\t\t{times: [{\"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n\t];\n```\n\nMake a pseudo-gantt chart thingy\n\n![Gantt chart](examples/timeline4.png)\n\nwith icons\n\n![Icon chart](examples/timeline5.png)\n\nFor your *really* long charts, it supports scrolling. It can even do things on hover, click, and scroll for when someone accidentally interacts with your chart.\n\nYou can also specify an optional `class` key in the data dictionary. This will label each timeline rectangle item within the visualization with the following id property: \"timelineItem_\"+class. For example, this data\n\n```js\nvar testData = [\n\t{class: \"pA\", label: \"person a\", times: [\n\t\t{\"starting_time\": 1355752800000, \"ending_time\": 1355759900000},\n\t\t{\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n\t{class: \"pB\", label: \"person b\", times: [\n\t\t{\"starting_time\": 1355759910000, \"ending_time\": 1355761900000}]},\n\t{class: \"pC\", label: \"person c\", times: [\n\t\t{\"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n\t];\n```\nwould generate `<rect>` with the following classes: `timelineItem_pA`,`timelineItem_pB`,`timelineItem_pC`. This means that you can dynamically change the visual properties of each timeline item using JQuery like so: `$(\".timelineSeries_pA\").css(\"fill\",\"blue\");`.\nIf no custom class is provided, the class attribute will be generated sequentially in the order they have been provided in. e.g.: `timelineSeries_0`.\n\nAlso optional is an `id` field per data element.\n\n```js\nvar testData = [\n\t{label: \"person a\", times: [\n\t\t{\"starting_time\": 1355752800000, \"ending_time\": 1355759900000, \"id\": \"A1\"},\n\t\t{\"starting_time\": 1355767900000, \"ending_time\": 1355774400000, \"id\": \"A2\"}]}\n\t];\n```\n\nThis generates `<rect>`s with `A1` and `A2` as ids. If no id is provided, the id attribute will be generated sequentially in the order they have been provided in. e.g.: `timelineItem_0_0`.\n\nLook at the [examples](examples/example.html) for more details.\n\n## Data formats\n\nThe simplest data format only requires `starting_time` and `ending_time` for each series of data.\n```js\n[\n\t{times: [\n\t\t{\"starting_time\": 1355752800000, \"ending_time\": 1355759900000},\n\t\t{\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n\t{times: [\n\t\t{\"starting_time\": 1355759910000, \"ending_time\": 1355761900000}]}\n];\n```\n\n`label` can be added if you want names by each series of data. In order for this to properly show up, the timeline needs to be called with .stack()\n```js\n[\n\t{label: \"person a\", times: [\n\t\t{\"starting_time\": 1355752800000, \"ending_time\": 1355759900000},\n\t\t{\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n\t{label: \"person b\", times: [\n\t\t{\"starting_time\": 1355759910000, \"ending_time\": 1355761900000}]}\n];\n```\n\n`icon` can be added if you want icons by each series of data. In order for this to properly show up, the timeline needs to be called with .stack(). Icons and labels can also be mixed in together.\n```js\n[\n\t{icon: \"path/to/img.png\", times: [\n\t\t{\"starting_time\": 1355752800000, \"ending_time\": 1355759900000},\n\t\t{\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n\t{label: \"person b\", times: [\n\t\t{\"starting_time\": 1355759910000, \"ending_time\": 1355761900000}]}\n];\n```\n\n###  'times' elements array\n\nEach item in the times array must have `starting_time` and `ending_time`.  You could also specify optional `color` or `label` elements within a times item, as well as a [property mapped to a color](#colorpropertypropertyname).\n```js\n[\n\t {label: \"person a\", times: [{\"color\":\"green\", \"label\":\"Weeee\", \"starting_time\": 1355752800000, \"ending_time\": 1355759900000}, {\"color\":\"blue\", \"label\":\"Weeee\", \"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n\t {label: \"person b\", times: [{\"color\":\"pink\", \"label\":\"Weeee\", \"starting_time\": 1355759910000, \"ending_time\": 1355761900000}, ]},\n\t {label: \"person c\", times: [{\"color\":\"yellow\", \"label\":\"Weeee\", \"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n];\n```\n\n\n## Method Calls\n\nAll methods that take in arguments return the current settings if no argument is passed.\n\n### .width(width)\n\nsets the width of the timeline. If the width of the timeline is longer than the width of the svg object, the timeline will automatically scroll. The width of the timeline will default to the width of the svg if width is not set.\n\n### .height(height)\n\nsets the height of the timeline. The height of the timeline will be automatically calculated from the height of each item if height is not set on the timeline or the svg.\n\n### .itemHeight(height)\n\nsets the height of the data series in the timeline. Defaults to 20px.\n\n### .itemMargin(height)\n\nsets the margin between the data series in the timeline. Defaults to 5px.\n\n### .margin({left: , right: , top: , bottom: })\n\nsets the margin of the entire timeline inside of the svg. Defaults to 30px all around.\n\n### .display(\"circle\" | \"rect\")\n\nDisplays the data series as either circles or rectangles. Defaults to \"rect\".\n\n### .labelFormat(callback)\n\nregisters a function to be called when the text for the label needs to\nbe generated. Useful if your label looks like this:\n\n```\n{\n\ten: \"my label\",\n\tfr: \"mon étiquette\"\n}\n```\nThe callback function is passed the whatever the datum.label returns, so\nin this case it would be the object above. So the labelFormat might\nlook something like this:\n```js\n.labelFormat(function(label){ return label[currentLocale];})\n```\n\n### .tickFormat({format: , tickTime: , tickInterval: , tickSize: , numTicks: , tickValues})\n\nsets the formatting of the ticks in the timeline. Defaults to\n\n```js\n{\n\tformat: d3.time.format(\"%I %p\"),\n\ttickTime: d3.time.hours,\n\ttickInterval: 1,\n\ttickSize: 6\n}\n```\nTick interval/values can be set with:\n\n- ``tickTime`` and ``tickInterval``\n- ``numTicks`` and ``tickInterval``\n- ``tickValues``\n\n### .rotateTicks(degrees)\n\nsets the degree of rotation of the tickmarks. Defaults to no rotation (0 degrees).\n\n### .orient(\"bottom\" | \"top\")\n\nsets the placement of the axis. Defaults to bottom.\n\n### .colors(callback)\n\nsets the d3 color scale the data series in the timeline. Defaults to `d3.scale.category20()`.\n\n### .colorProperty(propertyName)\n\nsets the data item property name that maps your data items to your color scale. For example if you set your chart's `colors()` and `colorsProperty()` as follows:\n\n```js\nvar colorScale = d3.scale.ordinal().range(['#6b0000','#ef9b0f','#ffee00'])\n\t\t\t\t\t\t.domain(['apple','orange','lemon']);\n\nvar chart = d3.timelines()\n\t\t\t\t\t\t.colors( colorScale )\n\t\t\t\t\t\t.colorProperty('fruit');\n```\n\nAnd pass this dataset:\n\n```js\nvar testData = [\n\t{label: \"fruit 1\", fruit: \"orange\", times: [\n\t\t{\"starting_time\": 1355759910000, \"ending_time\": 1355761900000}]},\n\t{label: \"fruit 2\", fruit: \"apple\", times: [\n\t\t{\"starting_time\": 1355752800000, \"ending_time\": 1355759900000},\n\t\t{\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n\t{label: \"fruit3\", fruit: \"lemon\", times: [\n\t\t{\"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n\t];\n```\nYour chart's bar colors will be determined based on the value of the fruit property:\n\n![Color Timeline](examples/timeline7.png)\n\nYou can also set the color property for a specific time object:\n\n```js\nvar testData = [\n\t{label: \"fruit 2\", fruit: \"apple\", times: [\n\t\t{fruit: \"orange\", \"starting_time\": 1355752800000, \"ending_time\": 1355759900000},\n\t\t{\"starting_time\": 1355767900000, \"ending_time\": 1355774400000},\n\t\t{fruit: \"lemon\", \"starting_time\": 1355774400000, \"ending_time\": 1355775500000}]}\n\t];\n```\n\nProperties set in the time object will override the property set for the series:\n\n![Timeline With Per-Time Colors](examples/timeline8.png)\n\n### .beginning(date)\n\nsets the time that the timeline should start. If `beginning` and `ending` are not set, the timeline will calculate it based off of the smallest and largest times.\n\n### .ending(date)\n\nsets the time that the timeline should end. If `beginning` and `ending` are not set, the timeline will calculate it based off of the smallest and largest times.\n\n### .stack()\n\nTakes in no arguments. Toggles the stacking/unstacking of data series in the timeline. Needs to be true in order for icons and labels to show up properly.\n\n### .relativeTime()\n\nTakes in no arguments. Toggles the calculation and use of relative timestamps. The origin of the timeline will be set to 0 and the starting_time of the first data dictionary in the data array will be subtracted from every subsequent timestamp.\n\n### .showToday()\n\nTakes in no arguments. Toggles a vertical line showing the current Date.now() time. Uses showTodayFormat for the line formatting.\n\n### .showTodayFormat({marginTop: , marginBottom: , width: , color: })\n\nSets the formatting of the showToday line. Color cycle can also be of the format `rgb(x, y, z)`.\n\n### .showBorderLine()\n\nTakes in no arguments. Toggles a vertical line showing the borders of one specific timeline. Uses showBorderFormat for the line formatting.\n\n### .showBorderFormat({marginTop: , marginBottom:, width: , color: })\n\nSets the formatting of the showBorder line. Color cycle can also be of the format `rgb(x, y, z)`.\n\n### .showTimeAxis()\n\nTakes in no arguments. Toggles the visibility of the time axis.\n\n### .showTimeAxisTick()\n\nTakes in no arguments. Shows tick marks along the X axis according to the arguments for `showTimeAxisTickFormat`. Useful for datasets with a lot of stacked elements.\n\n![Timeline With tick marks](examples/timeline9.png)\n\n### .showTimeAxisTickFormat(format)\n\nFormat for `showTimeAxisTick`. Defaults to ```{stroke: \"stroke-dasharray\", spacing: \"4 10\"}```.\n\nDefaults to\n\n```js\n{\n\tmarginTop: 25,\n\tmarginBottom: 0,\n\twidth: 1,\n\tcolor: colorCycle\n}\n```\n\n### .rowSeparators(color)\n\nSets the display of horizontal lines betweens rows.\n\n### .background(color)\n\nSets the background of the rows. Useful for creating a continuous effect when there are gaps in your data.\n\n### .hover(callback)\n\ntakes in a callback called on mousemove of the timeline data. Example\n\n```js\nd3.timelines()\n\t.hover(function (d, i, datum) {\n\t\t// d is the current rendering object\n\t\t// i is the index during d3 rendering\n\t\t// datum is the data object\n\t});\n```\n\n### .xAxisClass\n\nDefault is timeline-xAxis, but can be used to set any class.\n\n### .allowZoom\n\nDefault is true. Takes a boolean.  If set to false, does not allow zooming.\n\n### .mouseover(callback)\n\ntakes in a callback called on mouseover of the timeline data. Example\n\n```js\nd3.timelines()\n\t.mouseover(function (d, i, datum) {\n\t\t// d is the current rendering object\n\t\t// i is the index during d3 rendering\n\t\t// datum is the data object\n\t});\n```\n\n### .mouseout(callback)\n\ntakes in a callback called on mouseout of the timeline data. Example\n\n```js\nd3.timelines()\n\t.mouseout(function (d, i, datum) {\n\t\t// d is the current rendering object\n\t\t// i is the index during d3 rendering\n\t\t// datum is the data object\n\t});\n```\n\n### .click(callback)\n\ntakes in a callback called on click of the timeline data. Example\n\n```js\nd3.timelines()\n\t.click(function (d, i, datum) {\n\t\t// d is the current rendering object\n\t\t// i is the index during d3 rendering\n\t\t// datum is the data object\n\t});\n```\n\n### .scroll(callback)\n\ntakes in a callback called on scroll of the timeline data. Example\n\n```js\nd3.timelines()\n\t.scroll(function (x, scale) {\n\t\t// x is the current position of the scroll\n\t\t// scale is the scale of the axis used\n\t});\n```\n\n## Build\n\nTo build:\n- `npm install`\n- `npm test`\n- copy the build/d3-timelines.js to dist/d3-timelines.js\n\n## Previous work\n\nInspired by jiahuang - https://github.com/jiahuang/d3-timeline\n\n## License\n\nMIT\n"
  },
  {
    "path": "dist/d3-timelines.js",
    "content": "(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-axis'), require('d3-array'), require('d3-time-format'), require('d3-time'), require('d3-scale'), require('d3-selection'), require('d3-zoom')) :\n\ttypeof define === 'function' && define.amd ? define(['exports', 'd3-axis', 'd3-array', 'd3-time-format', 'd3-time', 'd3-scale', 'd3-selection', 'd3-zoom'], factory) :\n\t(factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3,global.d3,global.d3,global.d3,global.d3));\n}(this, function (exports,d3Axis,d3Array,d3TimeFormat,d3Time,d3Scale,d3Selection,d3Zoom) { 'use strict';\n\n\tvar timelines = function() {\n\t\t\tvar DISPLAY_TYPES = [\"circle\", \"rect\"];\n\n\t\t\tvar hover = function () {},\n\t\t\t\t\tmouseover = function () {},\n\t\t\t\t\tmouseout = function () {},\n\t\t\t\t\tclick = function () {},\n\t\t\t\t\tscroll = function () {},\n\t\t\t\t\tlabelFunction = function(label) { return label; },\n\t\t\t\t\tlabelFloat = 0,  // floats up this many pixels\n\t\t\t\t\tnavigateLeft = function () {},\n\t\t\t\t\tnavigateRight = function () {},\n\t\t\t\t\torient = \"bottom\",\n\t\t\t\t\twidth = null,\n\t\t\t\t\theight = null,\n\t\t\t\t\trowSeparatorsColor = null,\n\t\t\t\t\tbackgroundColor = null,\n\t\t\t\t\ttickFormat = {\n\t\t\t\t\t\tformat: d3TimeFormat.timeFormat(\"%I %p\"),\n\t\t\t\t\t\ttickTime: d3Time.timeHour,\n\t\t\t\t\t\ttickInterval: 1,\n\t\t\t\t\t\ttickSize: 6,\n\t\t\t\t\t\ttickValues: null\n\t\t\t\t\t},\n\t\t\t\t\tallowZoom = true,\n\t\t\t\t\taxisBgColor = \"white\",\n\t\t\t\t\tchartData = {},\n\t\t\t\t\tcolorCycle = d3Scale.scaleOrdinal(d3Scale.schemeCategory20),\n\t\t\t\t\tcolorPropertyName = null,\n\t\t\t\t\tdisplay = \"rect\",\n\t\t\t\t\tbeginning = 0,\n\t\t\t\t\tlabelMargin = 0,\n\t\t\t\t\tending = 0,\n\t\t\t\t\tmargin = {left: 30, right:30, top: 30, bottom:30},\n\t\t\t\t\tmaxZoom = 5,\n\t\t\t\t\tstacked = false,\n\t\t\t\t\trotateTicks = false,\n\t\t\t\t\ttimeIsRelative = false,\n\t\t\t\t\ttimeIsLinear = false,\n\t\t\t\t\tfullLengthBackgrounds = false,\n\t\t\t\t\titemHeight = 20,\n\t\t\t\t\titemMargin = 5,\n\t\t\t\t\tnavMargin = 60,\n\t\t\t\t\tshowTimeAxis = true,\n\t\t\t\t\tshowAxisTop = false,\n\t\t\t\t\tshowTodayLine = false,\n\t\t\t\t\ttimeAxisTick = false,\n\t\t\t\t\ttimeAxisTickFormat = {stroke: \"stroke-dasharray\", spacing: \"4 10\"},\n\t\t\t\t\tshowTodayFormat = {marginTop: 25, marginBottom: 0, width: 1, color: colorCycle},\n\t\t\t\t\tshowBorderLine = false,\n\t\t\t\t\tshowBorderFormat = {marginTop: 25, marginBottom: 0, width: 1, color: colorCycle},\n\t\t\t\t\tshowBorderLineClass = \"timeline-border-line\",\n\t\t\t\t\tshowAxisHeaderBackground = false,\n\t\t\t\t\tshowAxisNav = false,\n\t\t\t\t\tshowAxisCalendarYear = false,\n\t\t\t\t\txAxisClass = 'timeline-xAxis'\n\t\t\t\t;\n\n\t\t\tvar appendTimeAxis = function(g, xAxis, yPosition) {\n\n\t\t\t\tif(showAxisHeaderBackground){ appendAxisHeaderBackground(g, 0, 0); }\n\n\t\t\t\tif(showAxisNav){ appendTimeAxisNav(g); }\n\n\t\t\t\tvar axis = g.append(\"g\")\n\t\t\t\t\t.attr(\"class\", xAxisClass)\n\t\t\t\t\t.attr(\"transform\", \"translate(\" + 0 + \",\" + yPosition + \")\")\n\t\t\t\t\t.call(xAxis);\n\n\t\t\t\treturn axis;\n\t\t\t};\n\n\t\t\tvar appendTimeAxisCalendarYear = function (nav) {\n\t\t\t\tvar calendarLabel = beginning.getFullYear();\n\n\t\t\t\tif (beginning.getFullYear() != ending.getFullYear()) {\n\t\t\t\t\tcalendarLabel = beginning.getFullYear() + \"-\" + ending.getFullYear();\n\t\t\t\t}\n\n\t\t\t\tnav.append(\"text\")\n\t\t\t\t\t.attr(\"transform\", \"translate(\" + 20 + \", 0)\")\n\t\t\t\t\t.attr(\"x\", 0)\n\t\t\t\t\t.attr(\"y\", 14)\n\t\t\t\t\t.attr(\"class\", \"calendarYear\")\n\t\t\t\t\t.text(calendarLabel)\n\t\t\t\t;\n\t\t\t};\n\n\t\t\tvar appendTimeAxisNav = function (g) {\n\t\t\t\tvar timelineBlocks = 6;\n\t\t\t\tvar leftNavMargin = (margin.left - navMargin);\n\t\t\t\tvar incrementValue = (width - margin.left)/timelineBlocks;\n\t\t\t\tvar rightNavMargin = (width - margin.right - incrementValue + navMargin);\n\n\t\t\t\tvar nav = g.append('g')\n\t\t\t\t\t\t.attr(\"class\", \"axis\")\n\t\t\t\t\t\t.attr(\"transform\", \"translate(0, 20)\")\n\t\t\t\t\t;\n\n\t\t\t\tif(showAxisCalendarYear) { appendTimeAxisCalendarYear(nav); }\n\n\t\t\t\tnav.append(\"text\")\n\t\t\t\t\t.attr(\"transform\", \"translate(\" + leftNavMargin + \", 0)\")\n\t\t\t\t\t.attr(\"x\", 0)\n\t\t\t\t\t.attr(\"y\", 14)\n\t\t\t\t\t.attr(\"class\", \"chevron\")\n\t\t\t\t\t.text(\"<\")\n\t\t\t\t\t.on(\"click\", function () {\n\t\t\t\t\t\treturn navigateLeft(beginning, chartData);\n\t\t\t\t\t})\n\t\t\t\t;\n\n\t\t\t\tnav.append(\"text\")\n\t\t\t\t\t.attr(\"transform\", \"translate(\" + rightNavMargin + \", 0)\")\n\t\t\t\t\t.attr(\"x\", 0)\n\t\t\t\t\t.attr(\"y\", 14)\n\t\t\t\t\t.attr(\"class\", \"chevron\")\n\t\t\t\t\t.text(\">\")\n\t\t\t\t\t.on(\"click\", function () {\n\t\t\t\t\t\treturn navigateRight(ending, chartData);\n\t\t\t\t\t})\n\t\t\t\t;\n\t\t\t};\n\n\t\t\tvar appendAxisHeaderBackground = function (g, xAxis, yAxis) {\n\t\t\t\tg.insert(\"rect\")\n\t\t\t\t\t.attr(\"class\", \"row-green-bar\")\n\t\t\t\t\t.attr(\"x\", xAxis)\n\t\t\t\t\t.attr(\"width\", width)\n\t\t\t\t\t.attr(\"y\", yAxis)\n\t\t\t\t\t.attr(\"height\", itemHeight)\n\t\t\t\t\t.attr(\"fill\", axisBgColor);\n\t\t\t};\n\n\t\t\tvar appendTimeAxisTick = function(g, xAxis, maxStack) {\n\t\t\t\tg.append(\"g\")\n\t\t\t\t\t.attr(\"class\", \"axis\")\n\t\t\t\t\t.attr(\"transform\", \"translate(\" + 0 + \",\" + (margin.top + (itemHeight + itemMargin) * maxStack) + \")\")\n\t\t\t\t\t.attr(timeAxisTickFormat.stroke, timeAxisTickFormat.spacing)\n\t\t\t\t\t.call(xAxis.tickFormat(\"\").tickSize(-(margin.top + (itemHeight + itemMargin) * (maxStack - 1) + 3), 0, 0));\n\t\t\t};\n\n\t\t\tvar appendBackgroundBar = function (yAxisMapping, index, g, data, datum) {\n\t\t\t\tvar greenbarYAxis = ((itemHeight + itemMargin) * yAxisMapping[index]) + margin.top;\n\t\t\t\tg.selectAll(\"svg\")\n\t\t\t\t\t.data(data).enter()\n\t\t\t\t\t.insert(\"rect\", \":first-child\")\n\t\t\t\t\t.attr(\"class\", \"row-green-bar\")\n\t\t\t\t\t.attr(\"x\", fullLengthBackgrounds ? 0 : margin.left)\n\t\t\t\t\t.attr(\"width\", fullLengthBackgrounds ? width : (width - margin.right - margin.left))\n\t\t\t\t\t.attr(\"y\", greenbarYAxis)\n\t\t\t\t\t.attr(\"height\", itemHeight)\n\t\t\t\t\t.attr(\"fill\", backgroundColor instanceof Function ? backgroundColor(datum, index) : backgroundColor)\n\t\t\t\t;\n\t\t\t};\n\n\t\t\tvar appendLabel = function (gParent, yAxisMapping, index, hasLabel, datum) {\n\t\t\t\tvar fullItemHeight    = itemHeight + itemMargin;\n\t\t\t\tvar rowsDown          = margin.top + (fullItemHeight/2) + fullItemHeight * (yAxisMapping[index] || 1);\n\n\t\t\t\tgParent.append(\"text\")\n\t\t\t\t\t.attr(\"class\", \"timeline-label\")\n\t\t\t\t\t.attr(\"transform\", \"translate(\" + labelMargin + \",\" + rowsDown + \")\")\n\t\t\t\t\t.text(hasLabel ? labelFunction(datum.label) : datum.id)\n\t\t\t\t\t.on(\"click\", function (d, i) {\n\n\t\t\t\t\t\tconsole.log(\"label click!\");\n\t\t\t\t\t\tvar point = d3Selection.mouse(this);\n\t\t\t\t\t\tgParent.append(\"rect\")\n\t\t\t\t\t\t\t.attr(\"id\", \"clickpoint\")\n\t\t\t\t\t\t\t.attr(\"x\", point[0])\n\t\t\t\t\t\t\t.attr(\"width\", 10)\n\t\t\t\t\t\t\t.attr(\"height\", itemHeight);\n\n\t\t\t\t\t\tclick(d, index, datum, point, xScale.invert(point[0]));\n\t\t\t\t\t});\n\t\t\t};\n\n\t\t\t/*###########################\n\t\t\t####    START timelines    ###\n\t\t\t#############################*/\n\t\t\tfunction timelines (gParent) {\n\t\t\t\tvar gParentSize = gParent.node().getBoundingClientRect(); // the svg size\n\t\t\t\tvar gParentItem = d3Selection.select(gParent.node()); // the svg\n\n\t\t\t\tvar g = gParent.append(\"g\").attr(\"class\", \"container\");\n\n\t\t\t\tvar yAxisMapping = {},\n\t\t\t\t\tmaxStack = 1,\n\t\t\t\t\tminTime = 0,\n\t\t\t\t\tmaxTime = 0;\n\n\t\t\t\tsetWidth();\n\n\t\t\t\t// check if the user wants relative time\n\t\t\t\t// if so, substract the first timestamp from each subsequent timestamps\n\t\t\t\tif(timeIsRelative){\n\t\t\t\t\tg.each(function (d, i) {\n\t\t\t\t\t\tvar originTime = 0;\n\t\t\t\t\t\td.forEach(function (datum, index) {\n\t\t\t\t\t\t\tdatum.times.forEach(function (time, j) {\n\t\t\t\t\t\t\t\tif(index === 0 && j === 0){\n\t\t\t\t\t\t\t\t\toriginTime = time.starting_time;               //Store the timestamp that will serve as origin\n\t\t\t\t\t\t\t\t\ttime.starting_time = 0;                        //Set tahe origin\n\t\t\t\t\t\t\t\t\ttime.ending_time = time.ending_time - originTime;     //Store the relative time (millis)\n\t\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\t\ttime.starting_time = time.starting_time - originTime;\n\t\t\t\t\t\t\t\t\ttime.ending_time = time.ending_time - originTime;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\n\t\t\t\t}\n\n\t\t\t\t// check how many stacks we're gonna need\n\t\t\t\t// do this here so that we can draw the axis before the graph\n\t\t\t\tif (stacked || ending === 0 || beginning === 0) {\n\t\t\t\t\tg.each(function (d, i) {\n\t\t\t\t\t\td.forEach(function (datum, index) {\n\n\t\t\t\t\t\t\t// create y mapping for stacked graph\n\t\t\t\t\t\t\tif (stacked && Object.keys(yAxisMapping).indexOf(index) == -1) {\n\t\t\t\t\t\t\t\tyAxisMapping[index] = maxStack;\n\t\t\t\t\t\t\t\tmaxStack++;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// figure out beginning and ending times if they are unspecified\n\t\t\t\t\t\t\tdatum.times.forEach(function (time, i) {\n\t\t\t\t\t\t\t\tif(beginning === 0)\n\t\t\t\t\t\t\t\t\tif (time.starting_time < minTime || (minTime === 0 && timeIsRelative === false))\n\t\t\t\t\t\t\t\t\t\tminTime = time.starting_time;\n\t\t\t\t\t\t\t\tif(ending === 0)\n\t\t\t\t\t\t\t\t\tif (time.ending_time > maxTime)\n\t\t\t\t\t\t\t\t\t\tmaxTime = time.ending_time;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\n\t\t\t\t\tif (ending === 0) {\n\t\t\t\t\t\tending = maxTime;\n\t\t\t\t\t}\n\t\t\t\t\tif (beginning === 0) {\n\t\t\t\t\t\tbeginning = minTime;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar scaleFactor = (1/(ending - beginning)) * (width - margin.left - margin.right);\n\n\t\t\t\tfunction formatDays(d) {\n\t\t\t\t\t\tvar days = Math.floor(d / 86400),\n\t\t\t\t\t\t\t\thours = Math.floor((d - (days * 86400)) / 3600),\n\t\t\t\t\t\t\t\tminutes = Math.floor((d - (days * 86400) - (hours * 3600)) / 60),\n\t\t\t\t\t\t\t\tseconds = d - (days * 86400) - (hours * 3600) - (minutes * 60);\n\t\t\t\t\t\tvar output = '';\n\t\t\t\t\t\tif (seconds) {\n\t\t\t\t\t\t\toutput = seconds + 's';\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (minutes) {\n\t\t\t\t\t\t\t\toutput = minutes + 'm ' + output;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (hours) {\n\t\t\t\t\t\t\t\toutput = hours + 'h ' + output;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (days) {\n\t\t\t\t\t\t\t\toutput = days + 'd ' + output;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn output;\n\t\t\t\t};\n\n\t\t\t\tvar xScale;\n\t\t\t\tvar xAxis;\n\t\t\t\tif (orient == \"bottom\") {\n\t\t\t\t\txAxis = d3Axis.axisBottom();\n\t\t\t\t} else if (orient == \"top\") {\n\t\t\t\t\txAxis = d3Axis.axisTop();\n\t\t\t\t}\n\t\t\t\tif (timeIsLinear) {\n\t\t\t\t\txScale = d3Scale.scaleLinear()\n\t\t\t\t\t\t.domain([beginning, ending])\n\t\t\t\t\t\t.range([margin.left, width - margin.right]);\n\n\t\t\t\t\txAxis.scale(xScale)\n\t\t\t\t\t\t.tickFormat(formatDays)\n\t\t\t\t\t\t.tickValues(d3Array.range(0, ending, 86400));\n\t\t\t\t} else {\n\t\t\t\t\t\txScale = d3Scale.scaleTime()\n\t\t\t\t\t\t\t.domain([beginning, ending])\n\t\t\t\t\t\t\t.range([margin.left, width - margin.right]);\n\n\t\t\t\t\t\txAxis.scale(xScale)\n\t\t\t\t\t\t\t.tickFormat(tickFormat.format)\n\t\t\t\t\t\t\t.tickSize(tickFormat.tickSize);\n\t\t\t\t}\n\n\t\t\t\tif (tickFormat.tickValues !== null) {\n\t\t\t\t\txAxis.tickValues(tickFormat.tickValues);\n\t\t\t\t} else {\n\t\t\t\t\txAxis.tickArguments(tickFormat.numTicks || [tickFormat.tickTime, tickFormat.tickInterval]);\n\t\t\t\t}\n\n\t\t\t\t// append a view for zoom/pan support\n\t\t\t\tvar view = g.append(\"g\")\n\t\t\t\t\t.attr(\"class\", \"view\");\n\n\t\t\t\t// draw the chart\n\t\t\t\tg.each(function(d, i) {\n\t\t\t\t\tchartData = d;\n\t\t\t\t\td.forEach( function(datum, index){\n\t\t\t\t\t\tvar data = datum.times;\n\t\t\t\t\t\tdata.forEach(function(d) { d.name = datum.name });\n\n\t\t\t\t\t\tvar hasLabel = (typeof(datum.label) != \"undefined\");\n\n\t\t\t\t\t\t// issue warning about using id per data set. Ids should be individual to data elements\n\t\t\t\t\t\tif (typeof(datum.id) != \"undefined\") {\n\t\t\t\t\t\t\tconsole.warn(\"d3Timeline Warning: Ids per dataset is deprecated in favor of a 'class' key. Ids are now per data element.\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (backgroundColor) { appendBackgroundBar(yAxisMapping, index, g, data, datum); }\n\n\t\t\t\t\t\tview.selectAll(\"svg\")\n\t\t\t\t\t\t\t.data(data).enter()\n\t\t\t\t\t\t\t.append(function(d, i) {\n\t\t\t\t\t\t\t\t\t\treturn document.createElementNS(d3Selection.namespaces.svg, \"display\" in d? d.display:display);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.attr(\"x\", getXPos)\n\t\t\t\t\t\t\t.attr(\"y\", getStackPosition)\n\t\t\t\t\t\t\t.attr(\"width\", function (d, i) {\n\t\t\t\t\t\t\t\treturn (d.ending_time - d.starting_time) * scaleFactor;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.attr(\"cy\", function(d, i) {\n\t\t\t\t\t\t\t\t\treturn getStackPosition(d, i) + itemHeight/2;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.attr(\"cx\", getXPos)\n\t\t\t\t\t\t\t.attr(\"r\", itemHeight / 2)\n\t\t\t\t\t\t\t.attr(\"height\", itemHeight)\n\t\t\t\t\t\t\t.style(\"fill\", function(d, i){\n\t\t\t\t\t\t\t\tvar dColorPropName;\n\t\t\t\t\t\t\t\tif (d.color) return d.color;\n\t\t\t\t\t\t\t\tif( colorPropertyName ){\n\t\t\t\t\t\t\t\t\tdColorPropName = d[colorPropertyName];\n\t\t\t\t\t\t\t\t\tif ( dColorPropName ) {\n\t\t\t\t\t\t\t\t\t\treturn colorCycle( dColorPropName );\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\treturn colorCycle( datum[colorPropertyName] );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn colorCycle(index);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.on(\"mousemove\", function (d, i) {\n\t\t\t\t\t\t\t\thover(d, index, datum, i);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.on(\"mouseover\", function (d, i) {\n\t\t\t\t\t\t\t\tmouseover(d, i, datum, i);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.on(\"mouseout\", function (d, i) {\n\t\t\t\t\t\t\t\tmouseout(d, i, datum, i);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.on(\"click\", function (d, i) {\n\t\t\t\t\t\t\t\tvar point = d3Selection.mouse(this);\n\t\t\t\t\t\t\t\tvar selectedRect = d3Selection.select(this).node();\n\t\t\t\t\t\t\t\tvar selectorLabel = \"text#\" + selectedRect.id + '.textnumbers';\n\t\t\t\t\t\t\t\tvar selectedLabel = d3Selection.select(selectorLabel).node();\n\t\t\t\t\t\t\t\tclick(d, index, datum, selectedLabel, selectedRect, xScale.invert(point[0]));\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.attr(\"class\", function (d, i) {\n\t\t\t\t\t\t\t\treturn datum.class ? \"timelineSeries_\"+datum.class : \"timelineSeries_\"+index;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.attr(\"id\", function(d, i) {\n\t\t\t\t\t\t\t\t// use deprecated id field\n\t\t\t\t\t\t\t\tif (datum.id && !d.id) {\n\t\t\t\t\t\t\t\t\treturn 'timelineItem_'+datum.id;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn d.id ? d.id : \"timelineItem_\"+index+\"_\"+i;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\t// appends the labels to the boxes - DAY/HOUR LABEL\n\t\t\t\t\t\tview.selectAll(\"svg\")\n\t\t\t\t\t\t\t.data(data).enter()\n\t\t\t\t\t\t\t.append(\"text\")\n\t\t\t\t\t\t\t.attr(\"class\", \"textlabels\")\n\t\t\t\t\t\t\t.attr(\"id\", function(d) { return d.id })\n\t\t\t\t\t\t\t.attr(\"x\", function(d, i) { return getXTextPos(d, i, d.label, '.textlabels')})\n\t\t\t\t\t\t\t.attr(\"y\", (getStackTextPosition() - labelFloat))\n\t\t\t\t\t\t\t.text(function(d) {\n\t\t\t\t\t\t\t\treturn d.label;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.on(\"click\", function(d, i){\n\t\t\t\t\t\t\t\t// when clicking on the label, call the click for the rectangle with the same id\n\t\t\t\t\t\t\t\tvar point = d3Selection.mouse(this);\n\t\t\t\t\t\t\t\tvar id = this.id;\n\t\t\t\t\t\t\t\tvar labelSelector = \"text#\" + id + \".textnumbers\";\n\t\t\t\t\t\t\t\tvar selectedLabel = d3Selection.select(labelSelector).node();\n\t\t\t\t\t\t\t\tvar selector = \"rect#\" + id;\n\t\t\t\t\t\t\t\tvar selectedRect = d3Selection.select(selector).node();\n\t\t\t\t\t\t\t\tclick(d, index, datum, selectedLabel, selectedRect, xScale.invert(point[0]));\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\t// appends the NUMBER LABEL\n\t\t\t\t\t\tview.selectAll(\"svg\").data(data).enter()\n\t\t\t\t\t\t\t.filter(function(d) { return d.labelNumber !== undefined; })\n\t\t\t\t\t\t\t.append(\"text\")\n\t\t\t\t\t\t\t.attr(\"class\", \"textnumbers\")\n\t\t\t\t\t\t\t.attr(\"id\", function(d) { return d.id })\n\t\t\t\t\t\t\t.attr(\"x\", function(d, i) { return getXTextPos(d, i, d.labelNumber, '.textnumbers')})\n\t\t\t\t\t\t\t.attr(\"y\", getStackTextPosition)\n\t\t\t\t\t\t\t.text(function(d) {\n\t\t\t\t\t\t\t\treturn d.labelNumber;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.on(\"click\", function(d, i){\n\t\t\t\t\t\t\t\t// when clicking on the label, call the click for the rectangle with the same id\n\t\t\t\t\t\t\t\tvar point = d3Selection.mouse(this);\n\t\t\t\t\t\t\t\tvar id = this.id;\n\t\t\t\t\t\t\t\tvar selectedLabel = d3Selection.select(this).node();\n\t\t\t\t\t\t\t\tvar selector = \"rect#\" + id;\n\t\t\t\t\t\t\t\tvar selectedRect = d3Selection.select(selector).node();\n\t\t\t\t\t\t\t\tclick(d, index, datum, selectedLabel, selectedRect, xScale.invert(point[0]));\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\tif (rowSeparatorsColor) {\n\t\t\t\t\t\t\tvar lineYAxis = ( itemHeight + itemMargin / 2 + margin.top + (itemHeight + itemMargin) * yAxisMapping[index]);\n\t\t\t\t\t\t\tgParent.append(\"svg:line\")\n\t\t\t\t\t\t\t\t.attr(\"class\", \"row-separator\")\n\t\t\t\t\t\t\t\t.attr(\"x1\", 0 + margin.left)\n\t\t\t\t\t\t\t\t.attr(\"x2\", width - margin.right)\n\t\t\t\t\t\t\t\t.attr(\"y1\", lineYAxis)\n\t\t\t\t\t\t\t\t.attr(\"y2\", lineYAxis)\n\t\t\t\t\t\t\t\t.attr(\"stroke-width\", 1)\n\t\t\t\t\t\t\t\t.attr(\"stroke\", rowSeparatorsColor);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// add the label\n\t\t\t\t\t\tif (hasLabel) { appendLabel(gParent, yAxisMapping, index, hasLabel, datum); }\n\n\t\t\t\t\t\tif (typeof(datum.icon) !== \"undefined\") {\n\t\t\t\t\t\t\tgParent.append(\"image\")\n\t\t\t\t\t\t\t\t.attr(\"class\", \"timeline-label\")\n\t\t\t\t\t\t\t\t.attr(\"transform\", \"translate(\"+ 0 +\",\"+ (margin.top + (itemHeight + itemMargin) * yAxisMapping[index])+\")\")\n\t\t\t\t\t\t\t\t.attr(\"xlink:href\", datum.icon)\n\t\t\t\t\t\t\t\t.attr(\"width\", margin.left)\n\t\t\t\t\t\t\t\t.attr(\"height\", itemHeight);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfunction getStackPosition(d, i) {\n\t\t\t\t\t\t\tif (stacked) {\n\t\t\t\t\t\t\t\treturn margin.top + (itemHeight + itemMargin) * yAxisMapping[index];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn margin.top;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfunction getStackTextPosition(d, i) {\n\t\t\t\t\t\t\tif (stacked) {\n\t\t\t\t\t\t\t\treturn margin.top + (itemHeight + itemMargin) * yAxisMapping[index] + itemHeight * 0.75;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn margin.top + itemHeight * 0.75;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tvar belowLastItem = (margin.top + (itemHeight + itemMargin) * maxStack);\n\t\t\t\tvar aboveFirstItem = margin.top;\n\t\t\t\tvar timeAxisYPosition = showAxisTop ? aboveFirstItem : belowLastItem;\n\t\t\t\tvar gX;\n\t\t\t\tif (showTimeAxis) { gX = appendTimeAxis(g, xAxis, timeAxisYPosition); }\n\t\t\t\tif (timeAxisTick) { appendTimeAxisTick(g, xAxis, maxStack); }\n\n\t\t\t\tif (width > gParentSize.width) { // only if the scrolling should be allowed\n\t\t\t\t\tvar move = function() {\n\t\t\t\t\t\tg.select(\".view\")\n\t\t\t\t\t\t.attr(\"transform\", \"translate(\" + d3Selection.event.transform.x + \",0)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t + \"scale(\" + d3Selection.event.transform.k + \" 1)\");\n\n\t\t\t\t\t\tg.selectAll(\".timeline-xAxis\")\n\t\t\t\t\t\t\t.attr(\"transform\", function(d) {\n\t\t\t\t\t\t\t\t return \"translate(\" + d3Selection.event.transform.x + \", \" + timeAxisYPosition + \")\"\n\t\t\t\t\t\t\t\t\t\t\t+ \"scale(\" + d3Selection.event.transform.k + \" 1)\";\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\tvar new_xScale = d3Selection.event.transform.rescaleX(xScale);\n\t\t\t\t\t\tg.selectAll('.timeline-xAxis').call(function(d) { xAxis.scale(new_xScale); });\n\n\t\t\t\t\t\tvar xpos = -d3Selection.event.transform.x;\n\t\t\t\t\t\tscroll(xpos, xScale);\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\tvar zoom = d3Zoom.zoom()\n\t\t\t\t\t.scaleExtent([0, maxZoom]) // max zoom defaults to 5\n\t\t\t\t\t.translateExtent([[0, 0], [width, 0]]) // [x0, y0], [x1, y1] don't allow translating y-axis\n\t\t\t\t\t.on(\"zoom\", move);\n\n\t\t\t\tgParent\n\t\t\t\t\t.classed(\"scrollable\", true)\n\t\t\t\t\t.call(zoom);\n\n\t\t\t\tif (! allowZoom) {\n\t\t\t\t\tg.on(\"wheel\", function() {\n\t\t\t\t\t\td3Selection.event.preventDefault();\n\t\t\t\t\t\td3Selection.event.stopImmediatePropagation();\n\t\t\t\t\t});\n\t\t\t\t\tg.on(\"dblclick.zoom\", function() {\n\t\t\t\t\t\td3Selection.event.preventDefault();\n\t\t\t\t\t\td3Selection.event.stopImmediatePropagation();\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (rotateTicks) {\n\t\t\t\t\tg.selectAll(\".tick text\")\n\t\t\t\t\t\t.attr(\"transform\", function(d) {\n\t\t\t\t\t\t\treturn \"rotate(\" + rotateTicks + \")translate(\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t + (this.getBBox().width / 2 + 10) + \",\" // TODO: change this 10\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t + this.getBBox().height / 2 + \")\";\n\t\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// use the size of the elements added to the timeline to set the height\n\t\t\t\t//var gSize = g._groups[0][0].getBoundingClientRect();\n\t\t\t\tvar gSize = g.node().getBoundingClientRect();\n\t\t\t\tsetHeight();\n\n\t\t\t\tif (showBorderLine) {\n\t\t\t\t\tg.each(function (d, i) {\n\t\t\t\t\t\td.forEach(function (datum) {\n\t\t\t\t\t\t\tvar times = datum.times;\n\t\t\t\t\t\t\ttimes.forEach(function (time) {\n\t\t\t\t\t\t\t\tappendLine(xScale(time.starting_time), showBorderFormat, showBorderLineClass);\n\t\t\t\t\t\t\t\tappendLine(xScale(time.ending_time), showBorderFormat, showBorderLineClass);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (showTodayLine) {\n\t\t\t\t\tvar todayLine = xScale(new Date());\n\t\t\t\t\tappendLine(todayLine, showTodayFormat);\n\t\t\t\t}\n\n\t\t\t\tfunction getXPos(d, i) {\n\t\t\t\t\treturn margin.left + (d.starting_time - beginning) * scaleFactor;\n\t\t\t\t}\n\n\t\t\t\tfunction getTextWidth(text, font) {\n\t\t\t\t\t\t// re-use canvas object for better performance\n\t\t\t\t\t\tvar canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement(\"canvas\"));\n\t\t\t\t\t\tvar context = canvas.getContext(\"2d\");\n\t\t\t\t\t\tcontext.font = font;\n\t\t\t\t\t\tvar metrics = context.measureText(text);\n\t\t\t\t\t\treturn metrics.width;\n\t\t\t\t}\n\n\t\t\t\tfunction getXTextPos(d, i, text, style) {\n\t\t\t\t\tvar width = 0;\n\t\t\t\t\tif (d.ending_time) {\n\t\t\t\t\t\twidth = (((d.ending_time - d.starting_time) / 2) * scaleFactor);\n\t\t\t\t\t}\n\t\t\t\t\tif (text && style) {\n\t\t\t\t\t\t// get the style data for the class selector pass in\n\t\t\t\t\t\tvar textl = getComputedStyle(document.querySelector(style));\n\t\t\t\t\t\t// create a fontsize fontfamily string - 12pt Graphik\n\t\t\t\t\t\tvar fontInfo = textl.fontSize + ' ' + textl.fontFamily;\n\t\t\t\t\t\t// calculate the width of the text in that fontsize\n\t\t\t\t\t\tvar tl = getTextWidth(text, fontInfo);\n\t\t\t\t\t\t// subtract half of the text length from the xPosition to keep the text centered\n\t\t\t\t\t\tvar textLength = tl / 2;\n\t\t\t\t\t\tvar xPosition = margin.left + ((d.starting_time - beginning) * scaleFactor) + width - textLength;\n\t\t\t\t\t\treturn xPosition;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn margin.left + (d.starting_time - beginning) * scaleFactor + 5;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction setHeight() {\n\t\t\t\t\tif (!height && !gParentSize.height) {\n\t\t\t\t\t\tif (itemHeight) {\n\t\t\t\t\t\t\t// set height based off of item height\n\t\t\t\t\t\t\theight = gSize.height + gSize.top - gParentSize.top;\n\t\t\t\t\t\t\t// set bounding rectangle height\n\t\t\t\t\t\t\td3Selection.select(gParent).node().attr(\"height\", height);\n\t\t\t\t\t\t\t//select(view).node().attr(\"height\", height);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow \"height of the timeline is not set\";\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!height) {\n\t\t\t\t\t\t\theight = gParentSize.height;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tgParentItem.node().attr(\"height\", height);\n\t\t\t\t\t\t\t//view.node().attr(\"height\", height);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction setWidth() {\n\t\t\t\t\tif (!width && !gParentSize.width) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\twidth = gParentItem.node().attr(\"width\");\n\t\t\t\t\t\t\tif (!width) {\n\t\t\t\t\t\t\t\tthrow \"width of the timeline is not set. As of Firefox 27, timeline().with(x) needs to be explicitly set in order to render\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tconsole.log( err );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (!width && gParentSize.width) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\twidth = gParentSize.width;\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tconsole.log( err );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// if both are set, do nothing\n\t\t\t\t}\n\n\t\t\t\tfunction appendLine(lineScale, lineFormat, lineClass) {\n\t\t\t\t\tlineClass = lineClass || \"timeline-line\";\n\t\t\t\t\tview.append(\"svg:line\")\n\t\t\t\t\t\t.attr(\"x1\", lineScale)\n\t\t\t\t\t\t.attr(\"y1\", lineFormat.marginTop)\n\t\t\t\t\t\t.attr(\"x2\", lineScale)\n\t\t\t\t\t\t.attr(\"y2\", height - lineFormat.marginBottom)\n\t\t\t\t\t\t.attr(\"class\", lineClass)\n\t\t\t\t\t\t.style(\"stroke\", lineFormat.color)//\"rgb(6,120,155)\"\n\t\t\t\t\t\t.style(\"stroke-width\", lineFormat.width);\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// SETTINGS\n\n\t\t\ttimelines.margin = function (p) {\n\t\t\t\tif (!arguments.length) return margin;\n\t\t\t\tmargin = p;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.orient = function (orientation) {\n\t\t\t\tif (!arguments.length) return orient;\n\t\t\t\torient = orientation;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.itemHeight = function (h) {\n\t\t\t\tif (!arguments.length) return itemHeight;\n\t\t\t\titemHeight = h;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.itemMargin = function (h) {\n\t\t\t\tif (!arguments.length) return itemMargin;\n\t\t\t\titemMargin = h;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.navMargin = function (h) {\n\t\t\t\tif (!arguments.length) return navMargin;\n\t\t\t\tnavMargin = h;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.height = function (h) {\n\t\t\t\tif (!arguments.length) return height;\n\t\t\t\theight = h;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.width = function (w) {\n\t\t\t\tif (!arguments.length) return width;\n\t\t\t\twidth = w;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.display = function (displayType) {\n\t\t\t\tif (!arguments.length || (DISPLAY_TYPES.indexOf(displayType) == -1)) return display;\n\t\t\t\tdisplay = displayType;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.labelFormat = function(f) {\n\t\t\t\tif (!arguments.length) return labelFunction;\n\t\t\t\tlabelFunction = f;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.tickFormat = function (format) {\n\t\t\t\tif (!arguments.length) return tickFormat;\n\t\t\t\ttickFormat = format;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.allowZoom = function (zoomSetting) {\n\t\t\t\tif (!arguments.length) return allowZoom;\n\t\t\t\tallowZoom = zoomSetting;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.maxZoom = function (max) {\n\t\t\t\tif (!arguments.length) return maxZoom;\n\t\t\t\tmaxZoom = max;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.hover = function (hoverFunc) {\n\t\t\t\tif (!arguments.length) return hover;\n\t\t\t\thover = hoverFunc;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.mouseover = function (mouseoverFunc) {\n\t\t\t\tif (!arguments.length) return mouseover;\n\t\t\t\tmouseover = mouseoverFunc;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.mouseout = function (mouseoutFunc) {\n\t\t\t\tif (!arguments.length) return mouseout;\n\t\t\t\tmouseout = mouseoutFunc;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.click = function (clickFunc) {\n\t\t\t\tif (!arguments.length) return click;\n\t\t\t\tclick = clickFunc;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.scroll = function (scrollFunc) {\n\t\t\t\tif (!arguments.length) return scroll;\n\t\t\t\tscroll = scrollFunc;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.colors = function (colorFormat) {\n\t\t\t\tif (!arguments.length) return colorCycle;\n\t\t\t\tcolorCycle = colorFormat;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.beginning = function (b) {\n\t\t\t\tif (!arguments.length) return beginning;\n\t\t\t\tbeginning = b;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.ending = function (e) {\n\t\t\t\tif (!arguments.length) return ending;\n\t\t\t\tending = e;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.labelMargin = function (m) {\n\t\t\t\tif (!arguments.length) return labelMargin;\n\t\t\t\tlabelMargin = m;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.labelFloat = function (f) {\n\t\t\t\tif (!arguments.length) return labelFloat;\n\t\t\t\tlabelFloat = f;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.rotateTicks = function (degrees) {\n\t\t\t\tif (!arguments.length) return rotateTicks;\n\t\t\t\trotateTicks = degrees;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.stack = function () {\n\t\t\t\tstacked = !stacked;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.relativeTime = function() {\n\t\t\t\ttimeIsRelative = !timeIsRelative;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.linearTime = function() {\n\t\t\t\ttimeIsLinear = !timeIsLinear;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.showBorderLine = function () {\n\t\t\t\tshowBorderLine = !showBorderLine;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.showBorderFormat = function(borderFormat) {\n\t\t\t\tif (!arguments.length) return showBorderFormat;\n\t\t\t\tshowBorderFormat = borderFormat;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\t// CSS class for the lines added by showBorder\n\t\t\ttimelines.showBorderLineClass = function(borderClass) {\n\t\t\t\tif (!arguments.length) return showBorderLineClass;\n\t\t\t\tshowBorderLineClass = borderClass;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.showToday = function () {\n\t\t\t\tshowTodayLine = !showTodayLine;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.showTodayFormat = function(todayFormat) {\n\t\t\t\tif (!arguments.length) return showTodayFormat;\n\t\t\t\tshowTodayFormat = todayFormat;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.colorProperty = function(colorProp) {\n\t\t\t\tif (!arguments.length) return colorPropertyName;\n\t\t\t\tcolorPropertyName = colorProp;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.rowSeparators = function (color) {\n\t\t\t\tif (!arguments.length) return rowSeparatorsColor;\n\t\t\t\trowSeparatorsColor = color;\n\t\t\t\treturn timelines;\n\n\t\t\t};\n\n\t\t\ttimelines.background = function (color) {\n\t\t\t\tif (!arguments.length) return backgroundColor;\n\t\t\t\tbackgroundColor = color;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.showTimeAxis = function () {\n\t\t\t\tshowTimeAxis = !showTimeAxis;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.showAxisTop = function () {\n\t\t\t\tshowAxisTop = !showAxisTop;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.showAxisCalendarYear = function () {\n\t\t\t\tshowAxisCalendarYear = !showAxisCalendarYear;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.showTimeAxisTick = function () {\n\t\t\t\ttimeAxisTick = !timeAxisTick;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.fullLengthBackgrounds = function () {\n\t\t\t\tfullLengthBackgrounds = !fullLengthBackgrounds;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.showTimeAxisTickFormat = function(format) {\n\t\t\t\tif (!arguments.length) return timeAxisTickFormat;\n\t\t\t\ttimeAxisTickFormat = format;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.showAxisHeaderBackground = function(bgColor) {\n\t\t\t\tshowAxisHeaderBackground = !showAxisHeaderBackground;\n\t\t\t\tif(bgColor) { (axisBgColor = bgColor); }\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\t// CSS class for the x-axis\n\t\t\ttimelines.xAxisClass = function (axisClass) {\n\t\t\t\tif (!arguments.length) return xAxisClass;\n\t\t\t\txAxisClass = axisClass;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.navigate = function (navigateBackwards, navigateForwards) {\n\t\t\t\tif (!arguments.length) return [navigateLeft, navigateRight];\n\t\t\t\tnavigateLeft = navigateBackwards;\n\t\t\t\tnavigateRight = navigateForwards;\n\t\t\t\tshowAxisNav = !showAxisNav;\n\t\t\t\treturn timelines;\n\t\t\t};\n\n\t\t\ttimelines.version = function() {\n\t\t\t\treturn \"1.0.0\";\n\t\t\t};\n\n\t\t\treturn timelines;\n\t};\n\n\texports.timelines = timelines;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n}));"
  },
  {
    "path": "examples/days.html",
    "content": "<!doctype html>\n<html>\n<head>\n\t<script src=\"https://code.jquery.com/jquery-latest.min.js\"></script>\n\t<script src=\"https://d3js.org/d3.v4.min.js\" charset=\"utf-8\"></script>\n\t<script src=\"../dist/d3-timelines.js\"></script>\n\n\t<style type=\"text/css\">\n\n\t\t.timeline-xAxis path,\n\t\t.timeline-xAxis line {\n\t\t\tshape-rendering: crispEdges;\n\t\t}\n\n\t\t.timeline-xAxis text {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\t.textlabels {\n\t\t\tfont-size: 12pt;\n\t\t\tfont-family: Helvetica;\n\t\t}\n\n\t\t.textnumbers {\n\t\t\tfont-size: 18pt;\n\t\t\tfont-family: Helvetica;\n\t\t}\n\n\t\t.timeline-label {\n\t\t\tfont-family: sans-serif;\n\t\t\tfont-size: 12px;\n\t\t}\n\n\t\t.coloredDiv {\n\t\t\theight:20px; width:20px; float:left;\n\t\t}\n\t</style>\n\t<script type=\"text/javascript\">\n\t\twindow.onload = function() {\n\n\t\t\tformatDay = function(d) {\n\t\t\t\t\tvar days = Math.floor(d / 86400) +1,\n\t\t\t\t\t\t\thours = Math.floor((d - (days * 86400)) / 3600),\n\t\t\t\t\t\t\tminutes = Math.floor((d - (days * 86400) - (hours * 3600)) / 60);\n\t\t\t\t\t\t\t//seconds = d - (days * 86400) - (hours * 3600) - (minutes * 60);\n\t\t\t\t\tvar output = '';\n\t\t\t\t\t//if (seconds) {\n\t\t\t\t\t//\toutput = seconds + 's';\n\t\t\t\t\t//}\n\t\t\t\t\t//if (minutes) {\n\t\t\t\t\t//\t\toutput = minutes + 'm ' + output;\n\t\t\t\t\t//}\n\t\t\t\t\t//if (hours) {\n\t\t\t\t\t//\t\toutput = hours + 'h ' + output;\n\t\t\t\t\t//}\n\t\t\t\t\tif (days) {\n\t\t\t\t\t\t\toutput = days + 'd ' + output;\n\t\t\t\t\t}\n\t\t\t\t\tif (output === '') {\n\t\t\t\t\t\toutput = 'Start';\n\t\t\t\t\t}\n\t\t\t\t\treturn output;\n\t\t\t};\n\n\t\t\t// beginning has to be > 0\n\t/*\t\tvar testData = [\n//\t\t\t\t{name: \"Hydrocortisone\", times: [{\"starting_time\": 1, \"ending_time\": 691201, \"concentration\": \"10.0 uM\"}]},  // 0-8 days (8)\n//\t\t\t\t{name: \"SCF\", times: [{\"starting_time\": 691201, \"ending_time\": 1382401, \"concentration\": \"100.0 ng/mL\"}]}, // 8-16 days (8)\n\t\t\t\t{name: \"IL3\", times: [\n\t\t\t\t\t{\"starting_time\": 1382401, \"ending_time\": 2073601, \"concentration\": \"5.0 ng/mL\"},  // 16-24 days (8)\n\t\t\t\t\t{\"starting_time\": 2764801, \"ending_time\": 3024001, \"concentration\": \"5.0 ng/mL\"},   // 32-35 days, (3) after Epo\n\t\t\t\t]}, // 8 days, 3 days\n\t\t\t\t{name: \"Epo\", times: [{\"starting_time\": 2073601, \"ending_time\": 2764801, \"concentration\": \"3.0 Ul/ml\"}]}, // 24-32 days (8)\n//\t\t\t\t{name: \"Epo Feeder layer\", times: [{\"starting_time\": 3024001, \"ending_time\": 3369601, \"concentration\": \"3.0 Ul/ml\"}]},  // 35-39 days (4)\n//\t\t\t\t{name: \"Epo chemical Feeder layer\", times: [{\"starting_time\": 3369601, \"ending_time\": 3715201, \"concentration\": \"3.0 Ul/ml\"}]}  // 39-43 days (4)\n\t\t\t];\n*/\n\n\t\t\tvar testData = [\n\t\t\t\t\t{times:[\n\t\t\t\t\t\t{\"id\": \"day1\", \"label\": \"DAY\", \"labelNumber\": \"1\", \"starting_time\": 1, \"ending_time\": 86400},\n\t\t\t\t\t\t{\"id\": \"day2\", \"label\": \"DAY\", \"labelNumber\": \"2\", \"starting_time\": 86400, \"ending_time\": 86400*2},\n\t\t\t\t\t\t{\"id\": \"day3\", \"label\": \"DAY\", \"labelNumber\": \"3\", \"starting_time\": 86400*2, \"ending_time\": 86400*3},\n\t\t\t\t\t\t{\"id\": \"day4\", \"label\": \"DAY\", \"labelNumber\": \"4\", \"starting_time\": 86400*3, \"ending_time\": 86400*4},\n\t\t\t\t\t\t{\"id\": \"day5\", \"label\": \"DAY\", \"labelNumber\": \"5\", \"starting_time\": 86400*4, \"ending_time\": 86400*5}\n\t\t\t\t\t]},\n\t\t\t];\n\t\t\tvar width = 400;\n\n      // d3 v3\n\t\t\t// var colorScale = d3.scale.ordinal().range(['#ffffff']);\n\t\t\tvar colorScale = d3.scaleOrdinal().range(['#ffffff']);\n\t\t\tfunction buildTable() {\n\t\t\t\tvar tbody = d3.select(\"#assays > tbody\")\n\t\t\t\tvar rows = tbody.selectAll('tr').data(timepoints, function(d) { return d.id });\n\n\t\t\t\trows.enter()\n\t\t\t\t\t.append(\"tr\")\n\t\t\t\t\t.attr(\"id\", (d) => d.id)\n\t\t\t\t\t.html(function(d) {\n\t\t\t\t\t\tvar html = \"<td><select id=\\\"assay_\" + d.id + \"\\\" ><option value=\\\"dnase\\\">DNAseSeq</option><option value=\\\"rnase\\\">RNASeq</option></select></td>\\\n\t\t\t\t\t\t\t\t\t\t\t<td><input id=\\\"duration_\" + d.id + \"\\\" type=\\\"text\\\" value=\\\"\"+ formatDay(Math.round(d.duration)) + \"\\\"></input></td>\\\n\t\t\t\t\t\t\t\t\t\t\t<td><input id=\\\"replication_\" + d.id + \"\\\" type=\\\"text\\\"></input></td>\";\n\t\t\t\t\t\treturn html;\n\t\t\t\t\t})\n\t\t\t\t\t.attr(\"id\", function(d) { return d.id });\n\n\t\t\t\trows.exit().remove();\n\t\t\t}\n\n\t\t\tfunction secondFormat(num) {\n\t\t\t\tvar h = Math.floor( num / 3600 );\n\t\t\t\tvar m = Math.floor((num - h * 3600) / 60 );\n\t\t\t\tvar s = num - (h * 3600 + m * 60);\n\t\t\t\treturn ( h < 10 ? \"0\" + h : h ) + \":\" + ( m < 10 ? \"0\" + m : m ) + \":\" + ( s < 10 ? \"0\" + s : s );\n\t\t\t}\n\n\t\t\tvar timepoints = [];\n\t\t\tfunction timelineHover() {\n\t\t\t\tvar chart = d3.timelines()\n\t\t\t\t\t.linearTime()\n\t\t\t\t\t.itemHeight(60)\n\t\t\t\t\t.labelFloat(25)\n\t\t\t\t\t.itemMargin(0)\n\t\t\t\t\t.colors(colorScale)\n\t\t\t\t\t.showBorderLine()\n\t\t\t\t\t.showBorderFormat({marginTop: 30, marginBottom: 0, width: 3, color: 'black'})\n\t\t\t\t\t//.showTimeAxisTick()\n\t\t\t\t\t//.showTimeAxisTickFormat({stroke: \"4px\" })\n\t\t\t\t\t.margin({left:10, right:30, top:30, bottom:0})\n\t\t\t\t\t.hover(function (d, i, datum) {\n\t\t\t\t\t// d is the current rendering object\n\t\t\t\t\t// i is the index during d3 rendering\n\t\t\t\t\t// datum is the id object\n\t\t\t\t\t\tvar div = $('#hoverRes');\n\t\t\t\t\t\t//var colors = chart.colors();\n\t\t\t\t\t\t//div.find('.coloredDiv').css('background-color', colors(i));\n\t\t\t\t\t\tdiv.find('#name').text(datum.name);\n\t\t\t\t\t})\n\t\t\t\t\t.click(function (d, i, datum, labelElement, rectElement, duration) {\n\t\t\t\t\t\tvar ele = d3.select(rectElement);\n\t\t\t\t\t\tvar labelEle = d3.select(labelElement);\n\t\t\t\t\t\trectElement.duration = duration;\n\t\t\t\t\t\tif (timepoints.includes(rectElement)) {\n\t\t\t\t\t\t\tele.style(\"fill\", \"#ffffff\");\n\t\t\t\t\t\t\tlabelEle.style(\"fill\", \"#000000\");\n\t\t\t\t\t\t\tvar index = timepoints.indexOf(rectElement);\n\t\t\t\t\t\t\ttimepoints.splice(index, 1);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttimepoints.push(rectElement);\n\t\t\t\t\t\t\tlabelEle.style(\"fill\", \"#ffffff\");\n\t\t\t\t\t\t\tele.style(\"fill\", \"#e2ae79\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbuildTable();\n\t\t\t\t\t})\n\t\t\t\t\t.rotateTicks(45);\n\n\n\t\t\t\t// v3 returns [Array(1)] => [svg]\n\t\t\t\t// v4 returns\n\t\t\t\tvar svg = d3.select(\"#timeline\").append(\"svg\").attr(\"width\", width)\n\t\t\t\t\t.datum(testData).call(chart);\n\t\t\t}\n\n\t\t\ttimelineHover();\n/*\n\t\tfunction createTable() {\n\t\t\t\tvar table = $(\"<tbody></tbody>\");\n\t\t\t\tfor (var i = 0; i < testData.length; i++ ){\n\t\t\t\t\tvar step = testData[i];\n\t\t\t\t\tvar times = testData[i]['times'];\n\t\t\t\t\tfor (var j = 0; j < times.length; j++ ) {\n\t\t\t\t\t\tvar $line = $(\"<tr></tr>\");\n\t\t\t\t\t\t$line.append($(\"<td></td>\").html(step.name));\n\t\t\t\t\t\t$line.append($(\"<td></td>\").html(times[j].concentration));\n\t\t\t\t\t\t$line.append($(\"<td></td>\").html(formatDay(times[j].starting_time)));\n\t\t\t\t\t\t$line.append($(\"<td></td>\").html(formatDay(times[j].ending_time - times[j].starting_time)));\n\t\t\t\t\t\ttable.append($line);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn table;\n\t\t}\n\n\t\t\t$(\"#treatments\").append(createTable());\n\t\t*/\n\t\t}\n\t</script>\n</head>\n<body>\n\n\t<div>\n\t\t<h3>Differentiation</h3>\n\t<div id=\"protocol\">Erythroid - J.Namath Nature 2010</div>\n\t<div id=\"days\">11 Days</div>\n\t\t<div id=\"timeline\"></div>\n\t\t<div id=\"hoverRes\">\n\t\t\t<div class=\"coloredDiv\"></div>\n\t\t\t<div id=\"name\"></div>\n\t\t</div>\n\t</div>\n\t<div>&nbsp;\n\t</div>\n\t<div>\n\t\t<h3>Assays</h3>\n\t<table id=\"assays\">\n\t\t<thead>\n\t\t\t<tr>\n\t\t\t<th>Assay Type</th>\n\t\t\t<th>Timepoint</th>\n\t\t\t<th>Replication</th>\n\t\t\t</tr>\n\t\t</thead>\n\t  <tbody>\n\t\t</tbody>\n\t</div>\n\n</body>\n</html>\n"
  },
  {
    "path": "examples/days_scrollable.html",
    "content": "<!doctype html>\n<html>\n<head>\n\t<script src=\"https://code.jquery.com/jquery-latest.min.js\"></script>\n\t<script src=\"https://d3js.org/d3.v4.min.js\" charset=\"utf-8\"></script>\n\t<script src=\"../dist/d3-timelines.js\"></script>\n\n\t<style type=\"text/css\">\n\n\t\t.timeline-xAxis path,\n\t\t.timeline-xAxis line {\n\t\t\tshape-rendering: crispEdges;\n\t\t}\n\n\t\t.timeline-xAxis text {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\t.textlabels {\n\t\t\tfont-size: 12pt;\n\t\t\tfont-family: Helvetica;\n\t\t}\n\n\t\t.textnumbers {\n\t\t\tfont-size: 18pt;\n\t\t\tfont-family: Helvetica;\n\t\t}\n\n\t\t.timeline-label {\n\t\t\tfont-family: sans-serif;\n\t\t\tfont-size: 12px;\n\t\t}\n\n\t\t.coloredDiv {\n\t\t\theight:20px; width:20px; float:left;\n\t\t}\n\t</style>\n\t<script type=\"text/javascript\">\n\n\t\twindow.onload = function() {\n\n\t\t\tvar select = document.getElementById(\"selectNumber\");\n\t\t\tvar options = [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\"];\n\n\t\t\tfor (var i = 0; i < options.length; i++) {\n\t\t\t\t\tvar opt = options[i];\n\t\t\t\t\tvar el = document.createElement(\"option\");\n\t\t\t\t\tel.textContent = opt;\n\t\t\t\t\tel.value = opt;\n\t\t\t\t\tselect.appendChild(el);\n\t\t\t}\n\n\n\t\t\tvar formatDay = function(d) {\n\t\t\t\t\tvar days = Math.floor(d / 86400),\n\t\t\t\t\t\t\thours = Math.floor((d - (days * 86400)) / 3600),\n\t\t\t\t\t\t\tminutes = Math.floor((d - (days * 86400) - (hours * 3600)) / 60);\n\t\t\t\t\t\t\t//seconds = d - (days * 86400) - (hours * 3600) - (minutes * 60);\n\t\t\t\t\tvar output = '';\n\t\t\t\t\t//if (seconds) {\n\t\t\t\t\t//\toutput = seconds + 's';\n\t\t\t\t\t//}\n\t\t\t\t\t//if (minutes) {\n\t\t\t\t\t//\t\toutput = minutes + 'm ' + output;\n\t\t\t\t\t//}\n\t\t\t\t\t//if (hours) {\n\t\t\t\t\t//\t\toutput = hours + 'h ' + output;\n\t\t\t\t\t//}\n\t\t\t\t\tif (days) {\n\t\t\t\t\t\t\toutput = days + 'd ' + output;\n\t\t\t\t\t}\n\t\t\t\t\tif (output === '') {\n\t\t\t\t\t\toutput = 'Start';\n\t\t\t\t\t}\n\t\t\t\t\treturn output;\n\t\t\t};\n\n\t\t\t// beginning has to be > 0\n\t/*\t\tvar testData = [\n//\t\t\t\t{name: \"Hydrocortisone\", times: [{\"starting_time\": 1, \"ending_time\": 691201, \"concentration\": \"10.0 uM\"}]},  // 0-8 days (8)\n//\t\t\t\t{name: \"SCF\", times: [{\"starting_time\": 691201, \"ending_time\": 1382401, \"concentration\": \"100.0 ng/mL\"}]}, // 8-16 days (8)\n\t\t\t\t{name: \"IL3\", times: [\n\t\t\t\t\t{\"starting_time\": 1382401, \"ending_time\": 2073601, \"concentration\": \"5.0 ng/mL\"},  // 16-24 days (8)\n\t\t\t\t\t{\"starting_time\": 2764801, \"ending_time\": 3024001, \"concentration\": \"5.0 ng/mL\"},   // 32-35 days, (3) after Epo\n\t\t\t\t]}, // 8 days, 3 days\n\t\t\t\t{name: \"Epo\", times: [{\"starting_time\": 2073601, \"ending_time\": 2764801, \"concentration\": \"3.0 Ul/ml\"}]}, // 24-32 days (8)\n//\t\t\t\t{name: \"Epo Feeder layer\", times: [{\"starting_time\": 3024001, \"ending_time\": 3369601, \"concentration\": \"3.0 Ul/ml\"}]},  // 35-39 days (4)\n//\t\t\t\t{name: \"Epo chemical Feeder layer\", times: [{\"starting_time\": 3369601, \"ending_time\": 3715201, \"concentration\": \"3.0 Ul/ml\"}]}  // 39-43 days (4)\n\t\t\t];\n*/\n\nvar marginLeft = 10;\nvar marginRight = 10;\n\n\t\tvar testData = [];\n\t\twindow.constructTimes = function(days) {\n\t\t\tvar width = 400;\n\t\t\tvar newWidth = 400;\n\t\t\tvar times = [];\n\t\t\tfor (var i = 1; i <= days; i++) {\n\t\t\t\ttimes.push({\"id\": \"day\" + i, \"label\": \"DAY\", \"labelNumber\": i, \"starting_time\":  (i * 86400) + 1, \"ending_time\": ((i + 1) * 86400)})\n\t\t\t}\n\t\t\ttestData = [\n\t\t\t\t\t{times:times},\n\t\t\t];\n\t\t\tvar boxWidth = 47;\n\t\t\tvar dataLength = testData[0].times.length;\n\t\t\tvar viewWidth = 400 / dataLength;\n\t\t\tvar sf = boxWidth/ viewWidth;\n\t\t\tvar newWidth = width;\n\t\t\tif (sf > 1) {\n\t\t\t\tnewWidth = Math.round(width * sf) + marginLeft + marginRight;\n\t\t\t} else {\n\t\t\t\twidth = (boxWidth * dataLength) + marginLeft + marginRight;\n\t\t\t\tnewWidth = width;\n\t\t\t}\n\t\t\treturn width, newWidth;\n\t\t}\n\n\t\t\tvar width, newWidth = constructTimes(10);\n\t\t\t// d3 v3\n\t\t\t// var colorScale = d3.scale.ordinal().range(['#ffffff']);\n\t\t\tvar colorScale = d3.scaleOrdinal().range(['#ffffff']);\n\t\t\tfunction buildTable() {\n\t\t\t\tvar tbody = d3.select(\"#assays > tbody\")\n\t\t\t\tvar rows = tbody.selectAll('tr').data(timepoints, function(d) { return d.id });\n\n\t\t\t\trows.enter()\n\t\t\t\t\t.append(\"tr\")\n\t\t\t\t\t.attr(\"id\", (d) => d.id)\n\t\t\t\t\t.html(function(d) {\n\t\t\t\t\t\tvar html = \"<td><select id=\\\"assay_\" + d.id + \"\\\" ><option value=\\\"dnase\\\">DNAseSeq</option><option value=\\\"rnase\\\">RNASeq</option></select></td>\\\n\t\t\t\t\t\t\t\t\t\t\t<td><input id=\\\"duration_\" + d.id + \"\\\" type=\\\"text\\\" value=\\\"\"+ formatDay(Math.round(d.duration)) + \"\\\"></input></td>\\\n\t\t\t\t\t\t\t\t\t\t\t<td><input id=\\\"replication_\" + d.id + \"\\\" type=\\\"text\\\"></input></td>\";\n\t\t\t\t\t\treturn html;\n\t\t\t\t\t})\n\t\t\t\t\t.attr(\"id\", function(d) { return d.id });\n\n\t\t\t\trows.exit().remove();\n\t\t\t}\n\n\t\t\tfunction secondFormat(num) {\n\t\t\t\tvar h = Math.floor( num / 3600 );\n\t\t\t\tvar m = Math.floor((num - h * 3600) / 60 );\n\t\t\t\tvar s = num - (h * 3600 + m * 60);\n\t\t\t\treturn ( h < 10 ? \"0\" + h : h ) + \":\" + ( m < 10 ? \"0\" + m : m ) + \":\" + ( s < 10 ? \"0\" + s : s );\n\t\t\t}\n\n\t\t\tvar timepoints = [];\n\t\t\tfunction timelineHover(width, newWidth) {\n\t\t\t\tvar chart = d3.timelines()\n\t\t\t\t\t.linearTime()\n\t\t\t\t\t.allowZoom(false)\n\t\t\t\t\t.itemHeight(60)\n\t\t\t\t\t.labelFloat(25)\n\t\t\t\t\t.itemMargin(0)\n\t\t\t\t\t.width(newWidth)\n\t\t\t\t\t.colors(colorScale)\n\t\t\t\t\t.showBorderLine()\n\t\t\t\t\t.showBorderFormat({marginTop: 30, marginBottom: 0, width: 3, color: 'black'})\n\t\t\t\t\t//.showTimeAxisTick()\n\t\t\t\t\t//.showTimeAxisTickFormat({stroke: \"4px\" })\n\t\t\t\t\t.margin({left: marginLeft, right:marginRight, top:30, bottom:0})\n\t\t\t\t\t.hover(function (d, i, datum) {\n\t\t\t\t\t// d is the current rendering object\n\t\t\t\t\t// i is the index during d3 rendering\n\t\t\t\t\t// datum is the id object\n\t\t\t\t\t\tvar div = $('#hoverRes');\n\t\t\t\t\t\t//var colors = chart.colors();\n\t\t\t\t\t\t//div.find('.coloredDiv').css('background-color', colors(i));\n\t\t\t\t\t\tdiv.find('#name').text(datum.name);\n\t\t\t\t\t})\n\t\t\t\t\t.click(function (d, i, datum, labelElement, rectElement, duration) {\n\t\t\t\t\t\tvar ele = d3.select(rectElement);\n\t\t\t\t\t\tvar labelEle = d3.select(labelElement);\n\t\t\t\t\t\trectElement.duration = duration;\n\t\t\t\t\t\tif (timepoints.includes(rectElement)) {\n\t\t\t\t\t\t\tele.style(\"fill\", \"#ffffff\");\n\t\t\t\t\t\t\tlabelEle.style(\"fill\", \"#000000\");\n\t\t\t\t\t\t\tvar index = timepoints.indexOf(rectElement);\n\t\t\t\t\t\t\ttimepoints.splice(index, 1);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttimepoints.push(rectElement);\n\t\t\t\t\t\t\tlabelEle.style(\"fill\", \"#ffffff\");\n\t\t\t\t\t\t\tele.style(\"fill\", \"#e2ae79\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbuildTable();\n\t\t\t\t\t})\n\t\t\t\t\t.rotateTicks(45);\n\n\n\t\t\t\t// v3 returns [Array(1)] => [svg]\n\t\t\t\t// v4 returns\n\t\t\t\tvar svg = d3.select(\"#timeline\").append(\"svg\").attr(\"width\", width)\n\t\t\t\t\t.datum(testData).call(chart);\n\t\t\t}\n\n\t\t\ttimelineHover(width, newWidth);\n/*\n\t\tfunction createTable() {\n\t\t\t\tvar table = $(\"<tbody></tbody>\");\n\t\t\t\tfor (var i = 0; i < testData.length; i++ ){\n\t\t\t\t\tvar step = testData[i];\n\t\t\t\t\tvar times = testData[i]['times'];\n\t\t\t\t\tfor (var j = 0; j < times.length; j++ ) {\n\t\t\t\t\t\tvar $line = $(\"<tr></tr>\");\n\t\t\t\t\t\t$line.append($(\"<td></td>\").html(step.name));\n\t\t\t\t\t\t$line.append($(\"<td></td>\").html(times[j].concentration));\n\t\t\t\t\t\t$line.append($(\"<td></td>\").html(formatDay(times[j].starting_time)));\n\t\t\t\t\t\t$line.append($(\"<td></td>\").html(formatDay(times[j].ending_time - times[j].starting_time)));\n\t\t\t\t\t\ttable.append($line);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn table;\n\t\t}\n\n\t\t\t$(\"#treatments\").append(createTable());\n\t\t*/\n\t\twindow.updateTimeline = function(number) {\n\t\t\t\t\td3.select(\"#timeline\").select('svg').remove();\n\t\t\t\t\ttimepoints = [];\n\t\t\t\t\tvar uwidth, unewWidth = constructTimes(number);\n\t\t\t\t\ttimelineHover(uwidth, unewWidth);\n\t\t\t\t}\n\n\t\t}\n\t</script>\n</head>\n<body>\n\n\t<div>\n\t\t<h3>Differentiation</h3>\n\t<div id=\"protocol\">Erythroid - J.Namath Nature 2010</div>\n\t<div id=\"days\">11 Days</div>\n\t\t<div id=\"timeline\"></div>\n\t\t<div>\n\t\t\t<select id=\"selectNumber\" onChange=\"window.updateTimeline(this.value);\"></select>\n\t\t</div>\n\t</div>\n\t<div>&nbsp;\n\t</div>\n\t<div>\n\t\t<h3>Assays</h3>\n\t<table id=\"assays\">\n\t\t<thead>\n\t\t\t<tr>\n\t\t\t<th>Assay Type</th>\n\t\t\t<th>Timepoint</th>\n\t\t\t<th>Replication</th>\n\t\t\t</tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t</tbody>\n\t</div>\n\n</body>\n</html>\n"
  },
  {
    "path": "examples/example.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <script src=\"https://code.jquery.com/jquery-latest.min.js\"></script>\n  <script src=\"https://d3js.org/d3.v4.min.js\" charset=\"utf-8\"></script>\n  <script src=\"../dist/d3-timelines.js\"></script>\n\n  <style type=\"text/css\">\n    .axis path,\n    .axis line {\n      fill: none;\n      stroke: black;\n      shape-rendering: crispEdges;\n    }\n\n    .axis text {\n      font-family: sans-serif;\n      font-size: 10px;\n    }\n\n    .timeline-label {\n      font-family: sans-serif;\n      font-size: 12px;\n    }\n\n    #timeline2 .axis {\n      transform: translate(0px,40px);\n      -ms-transform: translate(0px,40px); /* IE 9 */\n      -webkit-transform: translate(0px,40px); /* Safari and Chrome */\n      -o-transform: translate(0px,40px); /* Opera */\n      -moz-transform: translate(0px,40px); /* Firefox */\n    }\n\n    .coloredDiv {\n      height:20px; width:20px; float:left;\n    }\n  </style>\n  <script type=\"text/javascript\">\n    window.onload = function() {\n      var testData = [\n        {times: [{\"starting_time\": 1355752800000, \"ending_time\": 1355759900000}, {\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n        {times: [{\"starting_time\": 1355759910000, \"ending_time\": 1355761900000}, ]},\n        {times: [{\"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n      ];\n\n      var rectAndCircleTestData = [\n        {times: [{\"starting_time\": 1355752800000,\n                 \"display\": \"circle\"}, {\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n        {times: [{\"starting_time\": 1355759910000,\n        \"display\":\"circle\"}, ]},\n        {times: [{\"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n      ];\n\n      var labelTestData = [\n        {label: \"person a\", times: [{\"starting_time\": 1355752800000, \"ending_time\": 1355759900000}, {\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n        {label: \"person b\", times: [{\"starting_time\": 1355759910000, \"ending_time\": 1355761900000}, ]},\n        {label: \"person c\", times: [{\"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n      ];\n\n      var iconTestData = [\n        {class:\"jackie\", icon: \"jackie.png\", times: [\n          {\"starting_time\": 1355752800000, \"ending_time\": 1355759900000},\n          {\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n        {class:\"troll\", icon: \"troll.png\", times: [\n          {\"starting_time\": 1355759910000, \"ending_time\": 1355761900000,\n          \"display\":\"circle\"}, ]},\n        {class:\"wat\", icon: \"wat.png\", times: [\n          {\"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n      ];\n\n      var labelColorTestData = [\n        {label: \"person a\", times: [{\"color\":\"green\", \"label\":\"Weeee\", \"starting_time\": 1355752800000, \"ending_time\": 1355759900000}, {\"color\":\"blue\", \"label\":\"Weeee\", \"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n        {label: \"person b\", times: [{\"color\":\"pink\", \"label\":\"Weeee\", \"starting_time\": 1355759910000, \"ending_time\": 1355761900000}, ]},\n        {label: \"person c\", times: [{\"color\":\"yellow\", \"label\":\"Weeee\", \"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n      ];\n\n      var testDataWithColor = [\n        {label: \"fruit 1\", fruit: \"orange\", times: [\n          {\"starting_time\": 1355759910000, \"ending_time\": 1355761900000}]},\n        {label: \"fruit 2\", fruit: \"apple\", times: [\n          {\"starting_time\": 1355752800000, \"ending_time\": 1355759900000},\n          {\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n        {label: \"fruit3\", fruit: \"lemon\", times: [\n          {\"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n        ];\n\n      var testDataWithColorPerTime = [\n        {label: \"fruit 2\", fruit: \"apple\", times: [\n          {fruit: \"orange\", \"starting_time\": 1355752800000, \"ending_time\": 1355759900000},\n          {\"starting_time\": 1355767900000, \"ending_time\": 1355774400000},\n          {fruit: \"lemon\", \"starting_time\": 1355774400000, \"ending_time\": 1355775500000}]}\n        ];\n\n      var testDataRelative = [\n        {times: [{\"starting_time\": 1355752800000, \"ending_time\": 1355759900000}, {\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n        {times: [{\"starting_time\": 1355759910000, \"ending_time\": 1355761900000}]},\n        {times: [{\"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n      ];\n\n      var width = 500;\n      function timelineRect() {\n        var chart = d3.timelines();\n\n        var svg = d3.select(\"#timeline1\").append(\"svg\").attr(\"width\", width)\n          .datum(testData).call(chart);\n      }\n\n      function timelineRectNoAxis() {\n        var chart = d3.timelines().showTimeAxis();\n\n        var svg = d3.select(\"#timeline1_noaxis\").append(\"svg\").attr(\"width\", width)\n          .datum(testData).call(chart);\n      }\n\n      function timelineCircle() {\n        var chart = d3.timelines()\n          .tickFormat( //\n            {format: d3.timeFormat(\"%I %p\"),\n            tickTime: d3.timeHours,\n            tickInterval: 1,\n            tickSize: 30})\n          .display(\"circle\"); // toggle between rectangles and circles\n\n        var svg = d3.select(\"#timeline2\").append(\"svg\").attr(\"width\", width)\n          .datum(testData).call(chart);\n      }\n\n      function timelineRectAndCircle() {\n        var chart = d3.timelines();\n\n        var svg = d3.select(\"#timeline2_combine\").append(\"svg\").attr(\"width\", width)\n          .datum(rectAndCircleTestData).call(chart);\n      }\n\n      // the stacked, hover, scrollable\n      function timelineHover() {\n        var chart = d3.timelines()\n          .width(width*4)\n          .stack()\n          .margin({left:70, right:30, top:0, bottom:0})\n          .hover(function (d, i, datum) {\n          // d is the current rendering object\n          // i is the index during d3 rendering\n          // datum is the id object\n            var div = $('#hoverRes');\n            var colors = chart.colors();\n            div.find('.coloredDiv').css('background-color', colors(i))\n            div.find('#name').text(datum.label);\n          })\n          .click(function (d, i, datum) {\n            alert(datum.label);\n          })\n          .scroll(function (x, scale) {\n            $(\"#scrolled_date\").text(scale.invert(x) + \" to \" + scale.invert(x+width));\n          });\n\n        var svg = d3.select(\"#timeline3\").append(\"svg\").attr(\"width\", width)\n          .datum(labelTestData).call(chart);\n      }\n\n      function timelineStackedIcons() {\n        var chart = d3.timelines()\n          .beginning(1355752800000) // we can optionally add beginning and ending times to speed up rendering a little\n          .ending(1355774400000)\n          .showTimeAxisTick() // toggles tick marks\n          .stack() // toggles graph stacking\n          .margin({left:70, right:30, top:0, bottom:0})\n          ;\n        var svg = d3.select(\"#timeline5\").append(\"svg\").attr(\"width\", width)\n          .datum(iconTestData).call(chart);\n      }\n\n      function timelineLabelColor() {\n        var chart = d3.timelines()\n          .beginning(1355752800000) // we can optionally add beginning and ending times to speed up rendering a little\n          .ending(1355774400000)\n          .stack() // toggles graph stacking\n          .margin({left:70, right:30, top:0, bottom:0})\n          ;\n        var svg = d3.select(\"#timeline6\").append(\"svg\").attr(\"width\", width)\n          .datum(labelColorTestData).call(chart);\n      }\n\n      function timelineRotatedTicks() {\n        var chart = d3.timelines()\n          .rotateTicks(45);\n\n        var svg = d3.select(\"#timeline7\").append(\"svg\").attr(\"width\", width)\n          .datum(testData).call(chart);\n      }\n\n      function timelineRectColors() {\n        var colorScale = d3.scaleOrdinal().range(['#6b0000','#ef9b0f','#ffee00'])\n            .domain(['apple','orange','lemon']);\n\n        var chart = d3.timelines()\n            .colors( colorScale )\n            .colorProperty('fruit');\n\n        var svg = d3.select(\"#timelineColors\").append(\"svg\").attr(\"width\", width)\n          .datum(testDataWithColor).call(chart);\n      }\n\n      function timelineRectColorsPerTime() {\n        var colorScale = d3.scaleOrdinal().range(['#6b0000','#ef9b0f','#ffee00'])\n          .domain(['apple','orange','lemon']);\n        var chart = d3.timelines()\n          .colors( colorScale )\n          .colorProperty('fruit');\n        var svg = d3.select(\"#timelineColorsPerTime\").append(\"svg\").attr(\"width\", width)\n          .datum(testDataWithColorPerTime).call(chart);\n      }\n\n      function timelineRelativeTime() {\n        //This solution is for relative time is from\n        //http://stackoverflow.com/questions/11286872/how-do-i-make-a-custom-axis-formatter-for-hours-minutes-in-d3-js\n        var chart = d3.timelines()\n          .relativeTime()\n          .tickFormat({\n            format: function(d) { return d3.timeFormat(\"%H:%M\")(d) },\n            tickTime: d3.timeMinutes,\n            tickInterval: 30,\n            tickSize: 15,\n          });\n\n        var svg = d3.select(\"#timelineRelativeTime\").append(\"svg\").attr(\"width\", width)\n          .datum(testDataRelative).call(chart);\n      }\n\n      function timelineAxisTop() {\n        var chart = d3.timelines().showAxisTop().stack();\n\n        var svg = d3.select(\"#timelineAxisTop\").append(\"svg\").attr(\"width\", width)\n            .datum(testData).call(chart);\n      }\n\n      function timelineBgndTick() {\n        var chart = d3.timelines().stack().showTimeAxisTick().background('grey');\n\n        var svg = d3.select(\"#timelineBgndTick\").append(\"svg\").attr(\"width\", width)\n            .datum(testData).call(chart);\n      }\n\n      function timelineBgnd() {\n        var chart = d3.timelines().stack().background('grey');\n\n        var svg = d3.select(\"#timelineBgnd\").append(\"svg\").attr(\"width\", width)\n            .datum(testData).call(chart);\n      }\n\n   function timelineComplex() {\n        var chart = d3.timelines();\n     chart.stack();\n     chart.showTimeAxisTick();\n//     chart.showAxisTop();\n//     chart.showToday();\n//     chart.itemHeight(50);\n     chart.margin({left: 250, right: 0, top: 20, bottom: 0});\n     chart.itemMargin(0);\n     chart.labelMargin(25);\n\n     var backgroundColor = \"#FCFCFD\";\n     var altBackgroundColor = \"red\";\n     chart.background(function (datum, i) {\n       var odd = (i % 2) === 0;\n       return odd ? altBackgroundColor : backgroundColor;\n     });\n     chart.fullLengthBackgrounds();\n        var svg = d3.select(\"#timelineComplex\").append(\"svg\").attr(\"width\", width)\n            .datum(labelTestData).call(chart);\n      }\n\n      timelineRect();\n      timelineRectNoAxis();\n      timelineCircle();\n      timelineRectAndCircle();\n      timelineHover();\n      timelineStackedIcons();\n      timelineLabelColor();\n      timelineRotatedTicks();\n      timelineRectColors();\n      timelineRectColorsPerTime();\n      timelineRelativeTime();\n      timelineAxisTop();\n      timelineBgndTick();\n      timelineBgnd();\n      timelineComplex();\n    }\n  </script>\n</head>\n<body>\n  <div>\n    <h3>A simple timeline</h3>\n    <div id=\"timeline1\"></div>\n  </div>\n  <div>\n    <h3>A simple timeline without Axis</h3>\n    <div id=\"timeline1_noaxis\"></div>\n  </div>\n  <div>\n    <h3>It works with circles too</h3>\n    <div id=\"timeline2\"></div>\n  </div>\n  <div>\n    <h3>Combine circles and rectangles</h3>\n    <div id=\"timeline2_combine\"></div>\n  </div>\n  <div>\n    <h3>A stacked timeline with hover, click, and scroll events</h3>\n    <div id=\"timeline3\"></div>\n    <div id=\"hoverRes\">\n      <div class=\"coloredDiv\"></div>\n      <div id=\"name\"></div>\n      <div id=\"scrolled_date\"></div>\n    </div>\n  </div>\n  <div>\n    <h3>We can also use icons</h3>\n    <div id=\"timeline5\"></div>\n  </div>\n\n  <div>\n    <h3>We can change colors and put labels</h3>\n    <div id=\"timeline6\"></div>\n  </div>\n\n  <div>\n    <h3>We can also rotate tick mark labels</h3>\n    <div id=\"timeline7\"></div>\n  </div>\n\n  <div>\n    <h3>A timeline with colors mapped from the data</h3>\n    <div id=\"timelineColors\"></div>\n  </div>\n\n  <div>\n    <h3>A timeline with colors mapped from the data for individual time objects</h3>\n    <div id=\"timelineColorsPerTime\"></div>\n  </div>\n\n  <div>\n    <h3>A timeline with relative timepoints</h3>\n    <div width=\"100%\" id=\"timelineRelativeTime\"></div>\n  </div>\n\n  <div>\n    <h3>A stacked timeline with axis on top</h3>\n    <div width=\"100%\" id=\"timelineAxisTop\"></div>\n  </div>\n\n  <div>\n    <h3>A stacked timeline with backgrounds</h3>\n    <div width=\"100%\" id=\"timelineBgnd\"></div>\n  </div>\n\n  <div>\n    <h3>A stacked timeline with backgrounds and ticks</h3>\n    <div width=\"100%\" id=\"timelineBgndTick\"></div>\n  </div>\n\n  <div>\n    <h3>A complex timeline</h3>\n    <div width=\"100%\" id=\"timelineComplex\"></div>\n  </div>\n\n</body>\n</html>\n"
  },
  {
    "path": "examples/scrollable.html",
    "content": "<!doctype html>\n<html>\n<head>\n\t<script src=\"https://code.jquery.com/jquery-latest.min.js\"></script>\n\t<script src=\"https://d3js.org/d3.v4.min.js\" charset=\"utf-8\"></script>\n\t<script src=\"../dist/d3-timelines.js\"></script>\n\n\t<style type=\"text/css\">\n\t\t.axis path,\n\t\t.axis line {\n\t\t\tfill: none;\n\t\t\tstroke: black;\n\t\t\tshape-rendering: crispEdges;\n\t\t}\n\n\t\t.axis text {\n\t\t\tfont-family: sans-serif;\n\t\t\tfont-size: 10px;\n\t\t}\n\n\t\t.timeline-label {\n\t\t\tfont-family: sans-serif;\n\t\t\tfont-size: 12px;\n\t\t}\n\n\t\t.coloredDiv {\n\t\t\theight:20px; width:20px; float:left;\n\t\t}\n\t</style>\n\t<script type=\"text/javascript\">\n\t\twindow.onload = function() {\n\n\t\t\tvar labelTestData = [\n\t\t\t\t{label: \"person a\", times: [{\"starting_time\": 1355752800000, \"ending_time\": 1355759900000}, {\"starting_time\": 1355767900000, \"ending_time\": 1355774400000}]},\n\t\t\t\t{label: \"person b\", times: [{\"starting_time\": 1355759910000, \"ending_time\": 1355761900000}, ]},\n\t\t\t\t{label: \"person c\", times: [{\"starting_time\": 1355761910000, \"ending_time\": 1355763910000}]}\n\t\t\t];\n\n\t\t\tvar width = 500;\n\t\t\t// the stacked, hover, scrollable\n\t\t\tfunction timelineHover() {\n\t\t\t\tvar chart = d3.timelines()\n\t\t\t\t\t.width(width*4)\n\t\t\t\t\t.stack()\n\t\t\t\t\t.margin({left:70, right:30, top:0, bottom:0})\n\t\t\t\t\t.hover(function (d, i, datum) {\n\t\t\t\t\t// d is the current rendering object\n\t\t\t\t\t// i is the index during d3 rendering\n\t\t\t\t\t// datum is the id object\n\t\t\t\t\t\tvar div = $('#hoverRes');\n\t\t\t\t\t\tvar colors = chart.colors();\n\t\t\t\t\t\tdiv.find('.coloredDiv').css('background-color', colors(i))\n\t\t\t\t\t\tdiv.find('#name').text(datum.label);\n\t\t\t\t\t})\n\t\t\t\t\t.click(function (d, i, datum) {\n\t\t\t\t\t\talert(datum.label);\n\t\t\t\t\t})\n\t\t\t\t\t.scroll(function (x, scale) {\n\t\t\t\t\t\t$(\"#scrolled_date\").text(scale.invert(x) + \" to \" + scale.invert(x+width));\n\t\t\t\t\t});\n\n\t\t\t\tvar svg = d3.select(\"#timeline3\").append(\"svg\").attr(\"width\", width)\n\t\t\t\t\t.datum(labelTestData).call(chart);\n\t\t\t}\n\n\t\t\ttimelineHover();\n\t\t}\n\t</script>\n</head>\n<body>\n\t<div>\n\t\t<h3>A stacked timeline with hover, click, and scroll events</h3>\n\t\t<div id=\"timeline3\"></div>\n\t\t<div id=\"hoverRes\">\n\t\t\t<div class=\"coloredDiv\"></div>\n\t\t\t<div id=\"name\"></div>\n\t\t\t<div id=\"scrolled_date\"></div>\n\t\t</div>\n\t</div>\n</body>\n</html>\n"
  },
  {
    "path": "examples/sp500.csv",
    "content": "date,price\nJan 2000,1394.46\nFeb 2000,1366.42\nMar 2000,1498.58\nApr 2000,1452.43\nMay 2000,1420.6\nJun 2000,1454.6\nJul 2000,1430.83\nAug 2000,1517.68\nSep 2000,1436.51\nOct 2000,1429.4\nNov 2000,1314.95\nDec 2000,1320.28\nJan 2001,1366.01\nFeb 2001,1239.94\nMar 2001,1160.33\nApr 2001,1249.46\nMay 2001,1255.82\nJun 2001,1224.38\nJul 2001,1211.23\nAug 2001,1133.58\nSep 2001,1040.94\nOct 2001,1059.78\nNov 2001,1139.45\nDec 2001,1148.08\nJan 2002,1130.2\nFeb 2002,1106.73\nMar 2002,1147.39\nApr 2002,1076.92\nMay 2002,1067.14\nJun 2002,989.82\nJul 2002,911.62\nAug 2002,916.07\nSep 2002,815.28\nOct 2002,885.76\nNov 2002,936.31\nDec 2002,879.82\nJan 2003,855.7\nFeb 2003,841.15\nMar 2003,848.18\nApr 2003,916.92\nMay 2003,963.59\nJun 2003,974.5\nJul 2003,990.31\nAug 2003,1008.01\nSep 2003,995.97\nOct 2003,1050.71\nNov 2003,1058.2\nDec 2003,1111.92\nJan 2004,1131.13\nFeb 2004,1144.94\nMar 2004,1126.21\nApr 2004,1107.3\nMay 2004,1120.68\nJun 2004,1140.84\nJul 2004,1101.72\nAug 2004,1104.24\nSep 2004,1114.58\nOct 2004,1130.2\nNov 2004,1173.82\nDec 2004,1211.92\nJan 2005,1181.27\nFeb 2005,1203.6\nMar 2005,1180.59\nApr 2005,1156.85\nMay 2005,1191.5\nJun 2005,1191.33\nJul 2005,1234.18\nAug 2005,1220.33\nSep 2005,1228.81\nOct 2005,1207.01\nNov 2005,1249.48\nDec 2005,1248.29\nJan 2006,1280.08\nFeb 2006,1280.66\nMar 2006,1294.87\nApr 2006,1310.61\nMay 2006,1270.09\nJun 2006,1270.2\nJul 2006,1276.66\nAug 2006,1303.82\nSep 2006,1335.85\nOct 2006,1377.94\nNov 2006,1400.63\nDec 2006,1418.3\nJan 2007,1438.24\nFeb 2007,1406.82\nMar 2007,1420.86\nApr 2007,1482.37\nMay 2007,1530.62\nJun 2007,1503.35\nJul 2007,1455.27\nAug 2007,1473.99\nSep 2007,1526.75\nOct 2007,1549.38\nNov 2007,1481.14\nDec 2007,1468.36\nJan 2008,1378.55\nFeb 2008,1330.63\nMar 2008,1322.7\nApr 2008,1385.59\nMay 2008,1400.38\nJun 2008,1280\nJul 2008,1267.38\nAug 2008,1282.83\nSep 2008,1166.36\nOct 2008,968.75\nNov 2008,896.24\nDec 2008,903.25\nJan 2009,825.88\nFeb 2009,735.09\nMar 2009,797.87\nApr 2009,872.81\nMay 2009,919.14\nJun 2009,919.32\nJul 2009,987.48\nAug 2009,1020.62\nSep 2009,1057.08\nOct 2009,1036.19\nNov 2009,1095.63\nDec 2009,1115.1\nJan 2010,1073.87\nFeb 2010,1104.49\nMar 2010,1140.45\n"
  },
  {
    "path": "examples/timeline.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <script src=\"https://code.jquery.com/jquery-latest.min.js\"></script>\n  <script src=\"https://d3js.org/d3.v4.min.js\" charset=\"utf-8\"></script>\n  <script src=\"../dist/d3-timelines.js\"></script>\n\n  <style type=\"text/css\">\n    .axis path,\n    .axis line {\n      fill: none;\n      stroke: black;\n      shape-rendering: crispEdges;\n    }\n\n    .axis text {\n      font-family: sans-serif;\n      font-size: 10px;\n    }\n\n    .timeline-label {\n      font-family: sans-serif;\n      font-size: 12px;\n    }\n\n    #timeline2 .axis {\n      transform: translate(0px,40px);\n      -ms-transform: translate(0px,40px); /* IE 9 */\n      -webkit-transform: translate(0px,40px); /* Safari and Chrome */\n      -o-transform: translate(0px,40px); /* Opera */\n      -moz-transform: translate(0px,40px); /* Firefox */\n    }\n\n    .coloredDiv {\n      height:20px; width:20px; float:left;\n    }\n  </style>\n  <script type=\"text/javascript\">\n    window.onload = function() {\n\n      var testData = [\n        {name: \"step1\", times: [{\"starting_time\": 0, \"ending_time\": 135}]},\n        {name: \"step2\", times: [{\"starting_time\": 120, \"ending_time\": 160}, ]},\n        {name: \"step3\", times: [{\"starting_time\": 160, \"ending_time\": 175}]}\n      ];\n\n      var width = 500;\n\n      function timelineHover() {\n        var chart = d3.timelines()\n          .relativeTime()\n          .tickFormat({\n            format: function(d) { return d3.timeFormat(\"%M\")(d) },\n            tickTime: d3.timeMinutes,\n            tickInterval: 15,\n            tickSize: 15,\n          })\n          .margin({left:70, right:30, top:0, bottom:0})\n          .hover(function (d, i, datum) {\n          // d is the current rendering object\n          // i is the index during d3 rendering\n          // datum is the id object\n            var div = $('#hoverRes');\n            var colors = chart.colors();\n            div.find('.coloredDiv').css('background-color', colors(i))\n            div.find('#name').text(datum.name);\n          })\n          .click(function (d, i, datum, selectedLabel, selectedRect, xVal) {\n            console.log(\"timelineHover\", datum.name);\n            console.log(\"point\", xVal)\n            $(\"#assays\").append(\"<div>\\\n            <label>Assay Type:</label><select><option value=\\\"dnase\\\">DNAseSeq</option><option value=\\\"rnase\\\">RNASeq</option></select> \\\n            <label>Assay Timepoint:</label><span>\"+ Math.round(xVal) + \"</span> \\\n            </div>\");\n          });\n\n        var svg = d3.select(\"#timeline\").append(\"svg\").attr(\"width\", width)\n          .datum(testData).call(chart);\n      }\n\n      timelineHover();\n\n    }\n  </script>\n</head>\n<body>\n\n  <div>\n    <h3>A stacked timeline with hover, click, and scroll events</h3>\n    <div id=\"timeline\"></div>\n    <div id=\"hoverRes\">\n      <div class=\"coloredDiv\"></div>\n      <div id=\"name\"></div>\n    </div>\n  </div>\n  <div>&nbsp;\n  </div>\n  <div id=\"assays\">\n    <form>\n    </form>\n  </div>\n\n</body>\n</html>\n"
  },
  {
    "path": "examples/timelineStacked.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <script src=\"https://code.jquery.com/jquery-latest.min.js\"></script>\n  <script src=\"https://d3js.org/d3.v4.min.js\" charset=\"utf-8\"></script>\n  <script src=\"../dist/d3-timelines.js\"></script>\n\n  <style type=\"text/css\">\n    .axis path,\n    .axis line {\n      fill: none;\n      stroke: black;\n      shape-rendering: crispEdges;\n    }\n\n    .axis text {\n      font-family: sans-serif;\n      font-size: 10px;\n    }\n\n    .timeline-label {\n      font-family: sans-serif;\n      font-size: 12px;\n    }\n\n    #timeline2 .axis {\n      transform: translate(0px,40px);\n      -ms-transform: translate(0px,40px); /* IE 9 */\n      -webkit-transform: translate(0px,40px); /* Safari and Chrome */\n      -o-transform: translate(0px,40px); /* Opera */\n      -moz-transform: translate(0px,40px); /* Firefox */\n    }\n\n    .coloredDiv {\n      height:20px; width:20px; float:left;\n    }\n  </style>\n  <script type=\"text/javascript\">\n    window.onload = function() {\n\n      var labelTestData = [\n        {label: \"step1\", times: [{\"starting_time\": 0, \"ending_time\": 135}]},\n        {label: \"step2\", times: [{\"starting_time\": 120, \"ending_time\": 160}, ]},\n        {label: \"step3\", times: [{\"starting_time\": 160, \"ending_time\": 175}]}\n      ];\n\n      var testData = [\n        {name: \"step1\", times: [{\"starting_time\": 0, \"ending_time\": 135}]},\n        {name: \"step2\", times: [{\"starting_time\": 120, \"ending_time\": 160}, ]},\n        {name: \"step3\", times: [{\"starting_time\": 160, \"ending_time\": 175}]}\n      ];\n\n      var width = 500;\n\n      function timelineStackedHover() {\n        var chart = d3.timelines()\n          .relativeTime()\n          .tickFormat({\n            format: function(d) { return d3.timeFormat(\"%M\")(d) },\n            tickTime: d3.timeMinutes,\n            tickInterval: 15,\n            tickSize: 15,\n          })\n          .stack()\n          .margin({left:70, right:30, top:0, bottom:0})\n          .hover(function (d, i, datum) {\n          // d is the current rendering object\n          // i is the index during d3 rendering\n          // datum is the id object\n            var div = $('#hoverRes');\n            var colors = chart.colors();\n            div.find('.coloredDiv').css('background-color', colors(i))\n            div.find('#name').text(datum.label);\n          })\n          .click(function (d, i, datum) {\n            console.log(\"timeStackedHover\", datum.label);\n          });\n\n        var svg = d3.select(\"#timeline3\").append(\"svg\").attr(\"width\", width)\n          .datum(labelTestData).call(chart);\n      }\n\n      function timelineHover() {\n        var chart = d3.timelines()\n          .relativeTime()\n          .tickFormat({\n            format: function(d) { return d3.timeFormat(\"%M\")(d) },\n            tickTime: d3.timeMinutes,\n            tickInterval: 15,\n            tickSize: 15,\n          })\n          .margin({left:70, right:30, top:0, bottom:0})\n          .hover(function (d, i, datum) {\n          // d is the current rendering object\n          // i is the index during d3 rendering\n          // datum is the id object\n            var div = $('#hoverRes1');\n            var colors = chart.colors();\n            div.find('.coloredDiv1').css('background-color', colors(i))\n            div.find('#name1').text(datum.name);\n          })\n          .click(function (d, i, datum, point) {\n            console.log(\"timelineHover\", datum.name);\n            console.log(\"point\", point)\n          });\n\n        var svg = d3.select(\"#timeline1\").append(\"svg\").attr(\"width\", width)\n          .datum(testData).call(chart);\n      }\n\n      timelineHover();\n      timelineStackedHover();\n\n    }\n  </script>\n</head>\n<body>\n\n  <div>\n    <h3>A stacked timeline with hover, click, and scroll events</h3>\n    <div id=\"timeline3\"></div>\n    <div id=\"hoverRes\">\n      <div class=\"coloredDiv\"></div>\n      <div id=\"name\"></div>\n    </div>\n  </div>\n  <div>\n    <h3>A timeline with hover, click, and scroll events</h3>\n    <div id=\"timeline1\"></div>\n    <div id=\"hoverRes1\">\n      <div class=\"coloredDiv1\"></div>\n      <div id=\"name1\"></div>\n    </div>\n  </div>\n\n</body>\n</html>\n"
  },
  {
    "path": "index.js",
    "content": "export { default as timelines } from \"./src/timelines\";\n"
  },
  {
    "path": "package.json",
    "content": "{\n\t\"name\": \"d3-timelines\",\n\t\"version\": \"1.3.1\",\n\t\"description\": \"A d3 v4 version of timeline. Can display single bar timelines, timelines with icons, and timelines that pan.\",\n\t\"keywords\": [\n\t\t\"d3\",\n\t\t\"d3-module\",\n\t\t\"d3-timelines\"\n\t],\n\t\"license\": \"BSD-3-Clause\",\n\t\"main\": \"build/d3-timelines.js\",\n\t\"jsnext:main\": \"index\",\n\t\"homepage\": \"https://github.com/denisemauldin/d3-timeline\",\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/denisemauldin/d3-timeline.git\"\n\t},\n\t\"scripts\": {\n\t\t\"pretest\": \"rm -rf build && mkdir build && rollup -c -f umd -n d3 -o build/d3-timelines.js -- index.js\",\n\t\t\"test\": \"tape 'test/**/*-test.js'\",\n\t\t\"prepare\": \"npm run test && uglifyjs build/d3-timelines.js -c -m -o build/d3-timelines.min.js\",\n\t\t\"postpublish\": \"zip -j build/d3-timelines.zip -- LICENSE README.md build/d3-timelines.js build/d3-timelines.min.js\"\n\t},\n\t\"peerDependencies\": {\n\t\t\"d3-array\": \"^1.2.0\",\n\t\t\"d3-axis\": \"^1.0.7\",\n\t\t\"d3-scale\": \"^1.0.6\",\n\t\t\"d3-selection\": \"^1.1.0\",\n\t\t\"d3-time\": \"^1.0.6\",\n\t\t\"d3-time-format\": \"^2.0.5\",\n\t\t\"d3-zoom\": \"^1.2.0\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@types/d3\": \"^4.5\",\n\t\t\"rollup\": \"0.27\",\n\t\t\"rollup-plugin-node-resolve\": \"^3.0.0\",\n\t\t\"tape\": \"4\",\n\t\t\"uglify-js\": \"2\"\n\t},\n\t\"dependencies\": {\n\t\t\"d3\": \"^4.9.1\",\n\t\t\"d3-array\": \"^1.2.0\",\n\t\t\"d3-axis\": \"^1.0.7\",\n\t\t\"d3-scale\": \"^1.0.6\",\n\t\t\"d3-selection\": \"^1.1.0\",\n\t\t\"d3-time\": \"^1.0.6\",\n\t\t\"d3-time-format\": \"^2.0.5\",\n\t\t\"d3-zoom\": \"^1.2.0\"\n\t}\n}\n"
  },
  {
    "path": "rollup.config.js",
    "content": "import nodeResolve from 'rollup-plugin-node-resolve';\n\nlet pkg = require(\"./package.json\");\nlet external = Object.keys(pkg.peerDependencies);\n\nexport default {\n\tentry: 'index.js',\n\tdest: 'bundle.js',\n\tformat: 'umd',\n\tmoduleName: 'd3-timeline',\n\texternal: external,\n\tglobals: {\n\t\t\"d3-axis\": \"d3\",\n\t\t\"d3-array\": \"d3\",\n\t\t\"d3-time-format\": \"d3\",\n\t\t\"d3-time\": \"d3\",\n\t\t\"d3-selection\": \"d3\",\n\t\t\"d3-scale\": \"d3\",\n\t\t\"d3-zoom\": \"d3\"\n\t},\n\tplugins: [nodeResolve({ jsnext: true, main: true})]\n};\n"
  },
  {
    "path": "src/timelines.js",
    "content": "\nimport { axisBottom, axisTop } from 'd3-axis';\nimport { range } from 'd3-array';\nimport { timeFormat } from 'd3-time-format';\nimport { timeHour } from 'd3-time';\nimport { scaleOrdinal, scaleTime, scaleLinear, schemeCategory20 } from 'd3-scale';\nimport { event, mouse, namespace, namespaces, select } from 'd3-selection';\nimport { zoom as d3z } from 'd3-zoom'\n\nvar timelines = function() {\n\t\tvar DISPLAY_TYPES = [\"circle\", \"rect\"];\n\n\t\tvar hover = function () {},\n\t\t\t\tmouseover = function () {},\n\t\t\t\tmouseout = function () {},\n\t\t\t\tclick = function () {},\n\t\t\t\tscroll = function () {},\n\t\t\t\tlabelFunction = function(label) { return label; },\n\t\t\t\tlabelFloat = 0,  // floats up this many pixels\n\t\t\t\tnavigateLeft = function () {},\n\t\t\t\tnavigateRight = function () {},\n\t\t\t\torient = \"bottom\",\n\t\t\t\twidth = null,\n\t\t\t\theight = null,\n\t\t\t\trowSeparatorsColor = null,\n\t\t\t\tbackgroundColor = null,\n\t\t\t\ttickFormat = {\n\t\t\t\t\tformat: timeFormat(\"%I %p\"),\n\t\t\t\t\ttickTime: timeHour,\n\t\t\t\t\ttickInterval: 1,\n\t\t\t\t\ttickSize: 6,\n\t\t\t\t\ttickValues: null\n\t\t\t\t},\n\t\t\t\tallowZoom = true,\n\t\t\t\taxisBgColor = \"white\",\n\t\t\t\tchartData = {},\n\t\t\t\tcolorCycle = scaleOrdinal(schemeCategory20),\n\t\t\t\tcolorPropertyName = null,\n\t\t\t\tdisplay = \"rect\",\n\t\t\t\tbeginning = 0,\n\t\t\t\tlabelMargin = 0,\n\t\t\t\tending = 0,\n\t\t\t\tmargin = {left: 30, right:30, top: 30, bottom:30},\n\t\t\t\tmaxZoom = 5,\n\t\t\t\tstacked = false,\n\t\t\t\trotateTicks = false,\n\t\t\t\ttimeIsRelative = false,\n\t\t\t\ttimeIsLinear = false,\n\t\t\t\tfullLengthBackgrounds = false,\n\t\t\t\titemHeight = 20,\n\t\t\t\titemMargin = 5,\n\t\t\t\tnavMargin = 60,\n\t\t\t\tshowTimeAxis = true,\n\t\t\t\tshowAxisTop = false,\n\t\t\t\tshowTodayLine = false,\n\t\t\t\ttimeAxisTick = false,\n\t\t\t\ttimeAxisTickFormat = {stroke: \"stroke-dasharray\", spacing: \"4 10\"},\n\t\t\t\tshowTodayFormat = {marginTop: 25, marginBottom: 0, width: 1, color: colorCycle},\n\t\t\t\tshowBorderLine = false,\n\t\t\t\tshowBorderFormat = {marginTop: 25, marginBottom: 0, width: 1, color: colorCycle},\n\t\t\t\tshowBorderLineClass = \"timeline-border-line\",\n\t\t\t\tshowAxisHeaderBackground = false,\n\t\t\t\tshowAxisNav = false,\n\t\t\t\tshowAxisCalendarYear = false,\n\t\t\t\txAxisClass = 'timeline-xAxis',\t\t\t\n\t\t    \t\txScale = null,\n\t\t\t\txAxis = null\n\t\t\t;\n\n\t\tvar appendTimeAxis = function(g, xAxis, yPosition) {\n\n\t\t\tif(showAxisHeaderBackground){ appendAxisHeaderBackground(g, 0, 0); }\n\n\t\t\tif(showAxisNav){ appendTimeAxisNav(g); }\n\n\t\t\tvar axis = g.append(\"g\")\n\t\t\t\t.attr(\"class\", xAxisClass)\n\t\t\t\t.attr(\"transform\", \"translate(\" + 0 + \",\" + yPosition + \")\")\n\t\t\t\t.call(xAxis);\n\n\t\t\treturn axis;\n\t\t};\n\n\t\tvar appendTimeAxisCalendarYear = function (nav) {\n\t\t\tvar calendarLabel = beginning.getFullYear();\n\n\t\t\tif (beginning.getFullYear() != ending.getFullYear()) {\n\t\t\t\tcalendarLabel = beginning.getFullYear() + \"-\" + ending.getFullYear();\n\t\t\t}\n\n\t\t\tnav.append(\"text\")\n\t\t\t\t.attr(\"transform\", \"translate(\" + 20 + \", 0)\")\n\t\t\t\t.attr(\"x\", 0)\n\t\t\t\t.attr(\"y\", 14)\n\t\t\t\t.attr(\"class\", \"calendarYear\")\n\t\t\t\t.text(calendarLabel)\n\t\t\t;\n\t\t};\n\n\t\tvar appendTimeAxisNav = function (g) {\n\t\t\tvar timelineBlocks = 6;\n\t\t\tvar leftNavMargin = (margin.left - navMargin);\n\t\t\tvar incrementValue = (width - margin.left)/timelineBlocks;\n\t\t\tvar rightNavMargin = (width - margin.right - incrementValue + navMargin);\n\n\t\t\tvar nav = g.append('g')\n\t\t\t\t\t.attr(\"class\", \"axis\")\n\t\t\t\t\t.attr(\"transform\", \"translate(0, 20)\")\n\t\t\t\t;\n\n\t\t\tif(showAxisCalendarYear) { appendTimeAxisCalendarYear(nav); }\n\n\t\t\tnav.append(\"text\")\n\t\t\t\t.attr(\"transform\", \"translate(\" + leftNavMargin + \", 0)\")\n\t\t\t\t.attr(\"x\", 0)\n\t\t\t\t.attr(\"y\", 14)\n\t\t\t\t.attr(\"class\", \"chevron\")\n\t\t\t\t.text(\"<\")\n\t\t\t\t.on(\"click\", function () {\n\t\t\t\t\treturn navigateLeft(beginning, chartData);\n\t\t\t\t})\n\t\t\t;\n\n\t\t\tnav.append(\"text\")\n\t\t\t\t.attr(\"transform\", \"translate(\" + rightNavMargin + \", 0)\")\n\t\t\t\t.attr(\"x\", 0)\n\t\t\t\t.attr(\"y\", 14)\n\t\t\t\t.attr(\"class\", \"chevron\")\n\t\t\t\t.text(\">\")\n\t\t\t\t.on(\"click\", function () {\n\t\t\t\t\treturn navigateRight(ending, chartData);\n\t\t\t\t})\n\t\t\t;\n\t\t};\n\n\t\tvar appendAxisHeaderBackground = function (g, xAxis, yAxis) {\n\t\t\tg.insert(\"rect\")\n\t\t\t\t.attr(\"class\", \"row-green-bar\")\n\t\t\t\t.attr(\"x\", xAxis)\n\t\t\t\t.attr(\"width\", width)\n\t\t\t\t.attr(\"y\", yAxis)\n\t\t\t\t.attr(\"height\", itemHeight)\n\t\t\t\t.attr(\"fill\", axisBgColor);\n\t\t};\n\n\t\tvar appendTimeAxisTick = function(g, xAxis, maxStack) {\n\t\t\tg.append(\"g\")\n\t\t\t\t.attr(\"class\", \"axis\")\n\t\t\t\t.attr(\"transform\", \"translate(\" + 0 + \",\" + (margin.top + (itemHeight + itemMargin) * maxStack) + \")\")\n\t\t\t\t.attr(timeAxisTickFormat.stroke, timeAxisTickFormat.spacing)\n\t\t\t\t.call(xAxis.tickFormat(\"\").tickSize(-(margin.top + (itemHeight + itemMargin) * (maxStack - 1) + 3), 0, 0));\n\t\t};\n\n\t\tvar appendBackgroundBar = function (yAxisMapping, index, g, data, datum) {\n\t\t\tvar greenbarYAxis = ((itemHeight + itemMargin) * yAxisMapping[index]) + margin.top;\n\t\t\tg.selectAll(\"svg\")\n\t\t\t\t.data(data).enter()\n\t\t\t\t.insert(\"rect\", \":first-child\")\n\t\t\t\t.attr(\"class\", \"row-green-bar\")\n\t\t\t\t.attr(\"x\", fullLengthBackgrounds ? 0 : margin.left)\n\t\t\t\t.attr(\"width\", fullLengthBackgrounds ? width : (width - margin.right - margin.left))\n\t\t\t\t.attr(\"y\", greenbarYAxis)\n\t\t\t\t.attr(\"height\", itemHeight)\n\t\t\t\t.attr(\"fill\", backgroundColor instanceof Function ? backgroundColor(datum, index) : backgroundColor)\n\t\t\t;\n\t\t};\n\n\t\tvar appendLabel = function (gParent, yAxisMapping, index, hasLabel, datum) {\n\t\t\tvar fullItemHeight    = itemHeight + itemMargin;\n\t\t\tvar rowsDown          = margin.top + (fullItemHeight/2) + fullItemHeight * (yAxisMapping[index] || 1);\n\n\t\t\tgParent.append(\"text\")\n\t\t\t\t.attr(\"class\", \"timeline-label\")\n\t\t\t\t.attr(\"transform\", \"translate(\" + labelMargin + \",\" + rowsDown + \")\")\n\t\t\t\t.text(hasLabel ? labelFunction(datum.label) : datum.id)\n\t\t\t\t.on(\"click\", function (d, i) {\n\n\t\t\t\t\tconsole.log(\"label click!\");\n\t\t\t\t\tvar point = mouse(this);\n\t\t\t\t\tgParent.append(\"rect\")\n\t\t\t\t\t\t.attr(\"id\", \"clickpoint\")\n\t\t\t\t\t\t.attr(\"x\", point[0])\n\t\t\t\t\t\t.attr(\"width\", 10)\n\t\t\t\t\t\t.attr(\"height\", itemHeight);\n\n\t\t\t\t\tclick(d, index, datum, point, xScale.invert(point[0]));\n\t\t\t\t});\n\t\t};\n\n\t\t/*###########################\n\t\t####    START timelines    ###\n\t\t#############################*/\n\t\tfunction timelines (gParent) {\n\t\t\tvar gParentSize = gParent.node().getBoundingClientRect(); // the svg size\n\t\t\tvar gParentItem = select(gParent.node()); // the svg\n\n\t\t\tvar g = gParent.append(\"g\").attr(\"class\", \"container\");\n\n\t\t\tvar yAxisMapping = {},\n\t\t\t\tmaxStack = 1,\n\t\t\t\tminTime = 0,\n\t\t\t\tmaxTime = 0;\n\n\t\t\tsetWidth();\n\n\t\t\t// check if the user wants relative time\n\t\t\t// if so, substract the first timestamp from each subsequent timestamps\n\t\t\tif(timeIsRelative){\n\t\t\t\tg.each(function (d, i) {\n\t\t\t\t\tvar originTime = 0;\n\t\t\t\t\td.forEach(function (datum, index) {\n\t\t\t\t\t\tdatum.times.forEach(function (time, j) {\n\t\t\t\t\t\t\tif(index === 0 && j === 0){\n\t\t\t\t\t\t\t\toriginTime = time.starting_time;               //Store the timestamp that will serve as origin\n\t\t\t\t\t\t\t\ttime.starting_time = 0;                        //Set tahe origin\n\t\t\t\t\t\t\t\ttime.ending_time = time.ending_time - originTime;     //Store the relative time (millis)\n\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\ttime.starting_time = time.starting_time - originTime;\n\t\t\t\t\t\t\t\ttime.ending_time = time.ending_time - originTime;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t}\n\n\t\t\t// check how many stacks we're gonna need\n\t\t\t// do this here so that we can draw the axis before the graph\n\t\t\tif (stacked || ending === 0 || beginning === 0) {\n\t\t\t\tg.each(function (d, i) {\n\t\t\t\t\td.forEach(function (datum, index) {\n\n\t\t\t\t\t\t// create y mapping for stacked graph\n\t\t\t\t\t\tif (stacked && Object.keys(yAxisMapping).indexOf(index) == -1) {\n\t\t\t\t\t\t\tyAxisMapping[index] = maxStack;\n\t\t\t\t\t\t\tmaxStack++;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// figure out beginning and ending times if they are unspecified\n\t\t\t\t\t\tdatum.times.forEach(function (time, i) {\n\t\t\t\t\t\t\tif(beginning === 0)\n\t\t\t\t\t\t\t\tif (time.starting_time < minTime || (minTime === 0 && timeIsRelative === false))\n\t\t\t\t\t\t\t\t\tminTime = time.starting_time;\n\t\t\t\t\t\t\tif(ending === 0)\n\t\t\t\t\t\t\t\tif (time.ending_time > maxTime)\n\t\t\t\t\t\t\t\t\tmaxTime = time.ending_time;\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tif (ending === 0) {\n\t\t\t\t\tending = maxTime;\n\t\t\t\t}\n\t\t\t\tif (beginning === 0) {\n\t\t\t\t\tbeginning = minTime;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar scaleFactor = (1/(ending - beginning)) * (width - margin.left - margin.right);\n\n\t\t\tfunction formatDays(d) {\n\t\t\t\t\tvar days = Math.floor(d / 86400),\n\t\t\t\t\t\t\thours = Math.floor((d - (days * 86400)) / 3600),\n\t\t\t\t\t\t\tminutes = Math.floor((d - (days * 86400) - (hours * 3600)) / 60),\n\t\t\t\t\t\t\tseconds = d - (days * 86400) - (hours * 3600) - (minutes * 60);\n\t\t\t\t\tvar output = '';\n\t\t\t\t\tif (seconds) {\n\t\t\t\t\t\toutput = seconds + 's';\n\t\t\t\t\t}\n\t\t\t\t\tif (minutes) {\n\t\t\t\t\t\t\toutput = minutes + 'm ' + output;\n\t\t\t\t\t}\n\t\t\t\t\tif (hours) {\n\t\t\t\t\t\t\toutput = hours + 'h ' + output;\n\t\t\t\t\t}\n\t\t\t\t\tif (days) {\n\t\t\t\t\t\t\toutput = days + 'd ' + output;\n\t\t\t\t\t}\n\t\t\t\t\treturn output;\n\t\t\t};\n\n\t\t\tif (orient == \"bottom\") {\n\t\t\t\txAxis = axisBottom();\n\t\t\t} else if (orient == \"top\") {\n\t\t\t\txAxis = axisTop();\n\t\t\t}\n\t\t\tif (timeIsLinear) {\n\t\t\t\txScale = scaleLinear()\n\t\t\t\t\t.domain([beginning, ending])\n\t\t\t\t\t.range([margin.left, width - margin.right]);\n\n\t\t\t\txAxis.scale(xScale)\n\t\t\t\t\t.tickFormat(formatDays)\n\t\t\t\t\t.tickValues(range(0, ending, 86400));\n\t\t\t} else {\n\t\t\t\t\txScale = scaleTime()\n\t\t\t\t\t\t.domain([beginning, ending])\n\t\t\t\t\t\t.range([margin.left, width - margin.right]);\n\n\t\t\t\t\txAxis.scale(xScale)\n\t\t\t\t\t\t.tickFormat(tickFormat.format)\n\t\t\t\t\t\t.tickSize(tickFormat.tickSize);\n\t\t\t}\n\n\t\t\tif (tickFormat.tickValues !== null) {\n\t\t\t\txAxis.tickValues(tickFormat.tickValues);\n\t\t\t} else {\n\t\t\t\txAxis.tickArguments(tickFormat.numTicks || [tickFormat.tickTime, tickFormat.tickInterval]);\n\t\t\t}\n\n\t\t\t// append a view for zoom/pan support\n\t\t\tvar view = g.append(\"g\")\n\t\t\t\t.attr(\"class\", \"view\");\n\n\t\t\t// draw the chart\n\t\t\tg.each(function(d, i) {\n\t\t\t\tchartData = d;\n\t\t\t\td.forEach( function(datum, index){\n\t\t\t\t\tvar data = datum.times;\n\t\t\t\t\tdata.forEach(function(d) { d.name = datum.name });\n\n\t\t\t\t\tvar hasLabel = (typeof(datum.label) != \"undefined\");\n\n\t\t\t\t\t// issue warning about using id per data set. Ids should be individual to data elements\n\t\t\t\t\tif (typeof(datum.id) != \"undefined\") {\n\t\t\t\t\t\tconsole.warn(\"d3Timeline Warning: Ids per dataset is deprecated in favor of a 'class' key. Ids are now per data element.\");\n\t\t\t\t\t}\n\n\t\t\t\t\tif (backgroundColor) { appendBackgroundBar(yAxisMapping, index, g, data, datum); }\n\n\t\t\t\t\tview.selectAll(\"svg\")\n\t\t\t\t\t\t.data(data).enter()\n\t\t\t\t\t\t.append(function(d, i) {\n\t\t\t\t\t\t\t\t\treturn document.createElementNS(namespaces.svg, \"display\" in d? d.display:display);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.attr(\"x\", getXPos)\n\t\t\t\t\t\t.attr(\"y\", getStackPosition)\n\t\t\t\t\t\t.attr(\"width\", function (d, i) {\n\t\t\t\t\t\t\treturn (d.ending_time - d.starting_time) * scaleFactor;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.attr(\"cy\", function(d, i) {\n\t\t\t\t\t\t\t\treturn getStackPosition(d, i) + itemHeight/2;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.attr(\"cx\", getXPos)\n\t\t\t\t\t\t.attr(\"r\", itemHeight / 2)\n\t\t\t\t\t\t.attr(\"height\", itemHeight)\n\t\t\t\t\t\t.style(\"fill\", function(d, i){\n\t\t\t\t\t\t\tvar dColorPropName;\n\t\t\t\t\t\t\tif (d.color) return d.color;\n\t\t\t\t\t\t\tif( colorPropertyName ){\n\t\t\t\t\t\t\t\tdColorPropName = d[colorPropertyName];\n\t\t\t\t\t\t\t\tif ( dColorPropName ) {\n\t\t\t\t\t\t\t\t\treturn colorCycle( dColorPropName );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\treturn colorCycle( datum[colorPropertyName] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn colorCycle(index);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.on(\"mousemove\", function (d, i) {\n\t\t\t\t\t\t\thover(d, index, datum, i);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.on(\"mouseover\", function (d, i) {\n\t\t\t\t\t\t\tmouseover(d, i, datum, i);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.on(\"mouseout\", function (d, i) {\n\t\t\t\t\t\t\tmouseout(d, i, datum, i);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.on(\"click\", function (d, i) {\n\t\t\t\t\t\t\tvar point = mouse(this);\n\t\t\t\t\t\t\tvar selectedRect = select(this).node();\n\t\t\t\t\t\t\tvar selectorLabel = \"text#\" + selectedRect.id + '.textnumbers';\n\t\t\t\t\t\t\tvar selectedLabel = select(selectorLabel).node();\n\t\t\t\t\t\t\tclick(d, index, datum, selectedLabel, selectedRect, xScale.invert(point[0]));\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.attr(\"class\", function (d, i) {\n\t\t\t\t\t\t\treturn datum.class ? \"timelineSeries_\"+datum.class : \"timelineSeries_\"+index;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.attr(\"id\", function(d, i) {\n\t\t\t\t\t\t\t// use deprecated id field\n\t\t\t\t\t\t\tif (datum.id && !d.id) {\n\t\t\t\t\t\t\t\treturn 'timelineItem_'+datum.id;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn d.id ? d.id : \"timelineItem_\"+index+\"_\"+i;\n\t\t\t\t\t\t})\n\t\t\t\t\t;\n\n\t\t\t\t\t// appends the labels to the boxes - DAY/HOUR LABEL\n\t\t\t\t\tview.selectAll(\"svg\")\n\t\t\t\t\t\t.data(data).enter()\n\t\t\t\t\t\t.append(\"text\")\n\t\t\t\t\t\t.attr(\"class\", \"textlabels\")\n\t\t\t\t\t\t.attr(\"id\", function(d) { return d.id })\n\t\t\t\t\t\t.attr(\"x\", function(d, i) { return getXTextPos(d, i, d.label, '.textlabels')})\n\t\t\t\t\t\t.attr(\"y\", (getStackTextPosition() - labelFloat))\n\t\t\t\t\t\t.text(function(d) {\n\t\t\t\t\t\t\treturn d.label;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.on(\"click\", function(d, i){\n\t\t\t\t\t\t\t// when clicking on the label, call the click for the rectangle with the same id\n\t\t\t\t\t\t\tvar point = mouse(this);\n\t\t\t\t\t\t\tvar id = this.id;\n\t\t\t\t\t\t\tvar labelSelector = \"text#\" + id + \".textnumbers\";\n\t\t\t\t\t\t\tvar selectedLabel = select(labelSelector).node();\n\t\t\t\t\t\t\tvar selector = \"rect#\" + id;\n\t\t\t\t\t\t\tvar selectedRect = select(selector).node();\n\t\t\t\t\t\t\tclick(d, index, datum, selectedLabel, selectedRect, xScale.invert(point[0]));\n\t\t\t\t\t\t})\n\t\t\t\t\t;\n\n\t\t\t\t\t// appends the NUMBER LABEL\n\t\t\t\t\tview.selectAll(\"svg\").data(data).enter()\n\t\t\t\t\t\t.filter(function(d) { return d.labelNumber !== undefined; })\n\t\t\t\t\t\t.append(\"text\")\n\t\t\t\t\t\t.attr(\"class\", \"textnumbers\")\n\t\t\t\t\t\t.attr(\"id\", function(d) { return d.id })\n\t\t\t\t\t\t.attr(\"x\", function(d, i) { return getXTextPos(d, i, d.labelNumber, '.textnumbers')})\n\t\t\t\t\t\t.attr(\"y\", getStackTextPosition)\n\t\t\t\t\t\t.text(function(d) {\n\t\t\t\t\t\t\treturn d.labelNumber;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.on(\"click\", function(d, i){\n\t\t\t\t\t\t\t// when clicking on the label, call the click for the rectangle with the same id\n\t\t\t\t\t\t\tvar point = mouse(this);\n\t\t\t\t\t\t\tvar id = this.id;\n\t\t\t\t\t\t\tvar selectedLabel = select(this).node();\n\t\t\t\t\t\t\tvar selector = \"rect#\" + id;\n\t\t\t\t\t\t\tvar selectedRect = select(selector).node();\n\t\t\t\t\t\t\tclick(d, index, datum, selectedLabel, selectedRect, xScale.invert(point[0]));\n\t\t\t\t\t\t})\n\t\t\t\t\t;\n\n\t\t\t\t\tif (rowSeparatorsColor) {\n\t\t\t\t\t\tvar lineYAxis = ( itemHeight + itemMargin / 2 + margin.top + (itemHeight + itemMargin) * yAxisMapping[index]);\n\t\t\t\t\t\tgParent.append(\"svg:line\")\n\t\t\t\t\t\t\t.attr(\"class\", \"row-separator\")\n\t\t\t\t\t\t\t.attr(\"x1\", 0 + margin.left)\n\t\t\t\t\t\t\t.attr(\"x2\", width - margin.right)\n\t\t\t\t\t\t\t.attr(\"y1\", lineYAxis)\n\t\t\t\t\t\t\t.attr(\"y2\", lineYAxis)\n\t\t\t\t\t\t\t.attr(\"stroke-width\", 1)\n\t\t\t\t\t\t\t.attr(\"stroke\", rowSeparatorsColor);\n\t\t\t\t\t}\n\n\t\t\t\t\t// add the label\n\t\t\t\t\tif (hasLabel) { appendLabel(gParent, yAxisMapping, index, hasLabel, datum); }\n\n\t\t\t\t\tif (typeof(datum.icon) !== \"undefined\") {\n\t\t\t\t\t\tgParent.append(\"image\")\n\t\t\t\t\t\t\t.attr(\"class\", \"timeline-label\")\n\t\t\t\t\t\t\t.attr(\"transform\", \"translate(\"+ 0 +\",\"+ (margin.top + (itemHeight + itemMargin) * yAxisMapping[index])+\")\")\n\t\t\t\t\t\t\t.attr(\"xlink:href\", datum.icon)\n\t\t\t\t\t\t\t.attr(\"width\", margin.left)\n\t\t\t\t\t\t\t.attr(\"height\", itemHeight);\n\t\t\t\t\t}\n\n\t\t\t\t\tfunction getStackPosition(d, i) {\n\t\t\t\t\t\tif (stacked) {\n\t\t\t\t\t\t\treturn margin.top + (itemHeight + itemMargin) * yAxisMapping[index];\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn margin.top;\n\t\t\t\t\t}\n\t\t\t\t\tfunction getStackTextPosition(d, i) {\n\t\t\t\t\t\tif (stacked) {\n\t\t\t\t\t\t\treturn margin.top + (itemHeight + itemMargin) * yAxisMapping[index] + itemHeight * 0.75;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn margin.top + itemHeight * 0.75;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tvar belowLastItem = (margin.top + (itemHeight + itemMargin) * maxStack);\n\t\t\tvar aboveFirstItem = margin.top;\n\t\t\tvar timeAxisYPosition = showAxisTop ? aboveFirstItem : belowLastItem;\n\t\t\tvar gX;\n\t\t\tif (showTimeAxis) { gX = appendTimeAxis(g, xAxis, timeAxisYPosition); }\n\t\t\tif (timeAxisTick) { appendTimeAxisTick(g, xAxis, maxStack); }\n\n\t\t\tif (width > gParentSize.width) { // only if the scrolling should be allowed\n\t\t\t\tvar move = function() {\n\t\t\t\t\tg.select(\".view\")\n\t\t\t\t\t.attr(\"transform\", \"translate(\" + event.transform.x + \",0)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t + \"scale(\" + event.transform.k + \" 1)\");\n\n\t\t\t\t\tg.selectAll(\".timeline-xAxis\")\n\t\t\t\t\t\t.attr(\"transform\", function(d) {\n\t\t\t\t\t\t\t return \"translate(\" + event.transform.x + \", \" + timeAxisYPosition + \")\"\n\t\t\t\t\t\t\t\t\t\t+ \"scale(\" + event.transform.k + \" 1)\";\n\t\t\t\t\t\t});\n\n\t\t\t\t\tvar new_xScale = event.transform.rescaleX(xScale);\n\t\t\t\t\tg.selectAll('.timeline-xAxis').call(function(d) { xAxis.scale(new_xScale); });\n\n\t\t\t\t\tvar xpos = -event.transform.x;\n\t\t\t\t\tscroll(xpos, xScale);\n\t\t\t\t};\n\t\t\t};\n\n\t\t\tif (! allowZoom) {\n\t\t\t\tvar zoom = d3z()\n\t\t\t\t\t.scaleExtent([0, maxZoom]) // max zoom defaults to 5\n\t\t\t\t\t.translateExtent([[0, 0], [width, 0]]) // [x0, y0], [x1, y1] don't allow translating y-axis\n\t\t\t\t\t.on(\"zoom\", move);\n\n\t\t\t\tgParent.classed(\"scrollable\", true)\n\t\t\t\t\t.call(zoom);\n\t\t\t\t\n\t\t\t\tg.on(\"wheel\", function() {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t});\n\t\t\t\tg.on(\"dblclick.zoom\", function() {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (rotateTicks) {\n\t\t\t\tg.selectAll(\".tick text\")\n\t\t\t\t\t.attr(\"transform\", function(d) {\n\t\t\t\t\t\treturn \"rotate(\" + rotateTicks + \")translate(\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t + (this.getBBox().width / 2 + 10) + \",\" // TODO: change this 10\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t + this.getBBox().height / 2 + \")\";\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\t// use the size of the elements added to the timeline to set the height\n\t\t\t//var gSize = g._groups[0][0].getBoundingClientRect();\n\t\t\tvar gSize = g.node().getBoundingClientRect();\n\t\t\tsetHeight();\n\n\t\t\tif (showBorderLine) {\n\t\t\t\tg.each(function (d, i) {\n\t\t\t\t\td.forEach(function (datum) {\n\t\t\t\t\t\tvar times = datum.times;\n\t\t\t\t\t\ttimes.forEach(function (time) {\n\t\t\t\t\t\t\tappendLine(xScale(time.starting_time), showBorderFormat, showBorderLineClass);\n\t\t\t\t\t\t\tappendLine(xScale(time.ending_time), showBorderFormat, showBorderLineClass);\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (showTodayLine) {\n\t\t\t\tvar todayLine = xScale(new Date());\n\t\t\t\tappendLine(todayLine, showTodayFormat);\n\t\t\t}\n\n\t\t\tfunction getXPos(d, i) {\n\t\t\t\treturn margin.left + (d.starting_time - beginning) * scaleFactor;\n\t\t\t}\n\n\t\t\tfunction getTextWidth(text, font) {\n\t\t\t\t\t// re-use canvas object for better performance\n\t\t\t\t\tvar canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement(\"canvas\"));\n\t\t\t\t\tvar context = canvas.getContext(\"2d\");\n\t\t\t\t\tcontext.font = font;\n\t\t\t\t\tvar metrics = context.measureText(text);\n\t\t\t\t\treturn metrics.width;\n\t\t\t}\n\n\t\t\tfunction getXTextPos(d, i, text, style) {\n\t\t\t\tvar width = 0;\n\t\t\t\tif (d.ending_time) {\n\t\t\t\t\twidth = (((d.ending_time - d.starting_time) / 2) * scaleFactor);\n\t\t\t\t}\n\t\t\t\tif (text && style) {\n\t\t\t\t\t// get the style data for the class selector pass in\n\t\t\t\t\tvar textl = getComputedStyle(document.querySelector(style));\n\t\t\t\t\t// create a fontsize fontfamily string - 12pt Graphik\n\t\t\t\t\tvar fontInfo = textl.fontSize + ' ' + textl.fontFamily;\n\t\t\t\t\t// calculate the width of the text in that fontsize\n\t\t\t\t\tvar tl = getTextWidth(text, fontInfo);\n\t\t\t\t\t// subtract half of the text length from the xPosition to keep the text centered\n\t\t\t\t\tvar textLength = tl / 2;\n\t\t\t\t\tvar xPosition = margin.left + ((d.starting_time - beginning) * scaleFactor) + width - textLength;\n\t\t\t\t\treturn xPosition;\n\t\t\t\t} else {\n\t\t\t\t\treturn margin.left + (d.starting_time - beginning) * scaleFactor + 5;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction setHeight() {\n\t\t\t\tif (!height && !gParentSize.height) {\n\t\t\t\t\tif (itemHeight) {\n\t\t\t\t\t\t// set height based off of item height\n\t\t\t\t\t\theight = gSize.height + gSize.top - gParentSize.top;\n\t\t\t\t\t\t// set bounding rectangle height\n\t\t\t\t\t\tselect(gParent).node().attr(\"height\", height);\n\t\t\t\t\t\t//select(view).node().attr(\"height\", height);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow \"height of the timeline is not set\";\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (!height) {\n\t\t\t\t\t\theight = gParentSize.height;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgParentItem.node().attr(\"height\", height);\n\t\t\t\t\t\t//view.node().attr(\"height\", height);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction setWidth() {\n\t\t\t\tif (!width && !gParentSize.width) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\twidth = gParentItem.node().attr(\"width\");\n\t\t\t\t\t\tif (!width) {\n\t\t\t\t\t\t\tthrow \"width of the timeline is not set. As of Firefox 27, timeline().with(x) needs to be explicitly set in order to render\";\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.log( err );\n\t\t\t\t\t}\n\t\t\t\t} else if (!width && gParentSize.width) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\twidth = gParentSize.width;\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.log( err );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// if both are set, do nothing\n\t\t\t}\n\n\t\t\tfunction appendLine(lineScale, lineFormat, lineClass) {\n\t\t\t\tlineClass = lineClass || \"timeline-line\";\n\t\t\t\tview.append(\"svg:line\")\n\t\t\t\t\t.attr(\"x1\", lineScale)\n\t\t\t\t\t.attr(\"y1\", lineFormat.marginTop)\n\t\t\t\t\t.attr(\"x2\", lineScale)\n\t\t\t\t\t.attr(\"y2\", height - lineFormat.marginBottom)\n\t\t\t\t\t.attr(\"class\", lineClass)\n\t\t\t\t\t.style(\"stroke\", lineFormat.color)//\"rgb(6,120,155)\"\n\t\t\t\t\t.style(\"stroke-width\", lineFormat.width);\n\t\t\t}\n\n\t\t}\n\n\t\t// SETTINGS\n\n\t\ttimelines.margin = function (p) {\n\t\t\tif (!arguments.length) return margin;\n\t\t\tmargin = p;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.orient = function (orientation) {\n\t\t\tif (!arguments.length) return orient;\n\t\t\torient = orientation;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.itemHeight = function (h) {\n\t\t\tif (!arguments.length) return itemHeight;\n\t\t\titemHeight = h;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.itemMargin = function (h) {\n\t\t\tif (!arguments.length) return itemMargin;\n\t\t\titemMargin = h;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.navMargin = function (h) {\n\t\t\tif (!arguments.length) return navMargin;\n\t\t\tnavMargin = h;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.height = function (h) {\n\t\t\tif (!arguments.length) return height;\n\t\t\theight = h;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.width = function (w) {\n\t\t\tif (!arguments.length) return width;\n\t\t\twidth = w;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.display = function (displayType) {\n\t\t\tif (!arguments.length || (DISPLAY_TYPES.indexOf(displayType) == -1)) return display;\n\t\t\tdisplay = displayType;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.labelFormat = function(f) {\n\t\t\tif (!arguments.length) return labelFunction;\n\t\t\tlabelFunction = f;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.tickFormat = function (format) {\n\t\t\tif (!arguments.length) return tickFormat;\n\t\t\ttickFormat = format;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.allowZoom = function (zoomSetting) {\n\t\t\tif (!arguments.length) return allowZoom;\n\t\t\tallowZoom = zoomSetting;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.maxZoom = function (max) {\n\t\t\tif (!arguments.length) return maxZoom;\n\t\t\tmaxZoom = max;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.hover = function (hoverFunc) {\n\t\t\tif (!arguments.length) return hover;\n\t\t\thover = hoverFunc;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.mouseover = function (mouseoverFunc) {\n\t\t\tif (!arguments.length) return mouseover;\n\t\t\tmouseover = mouseoverFunc;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.mouseout = function (mouseoutFunc) {\n\t\t\tif (!arguments.length) return mouseout;\n\t\t\tmouseout = mouseoutFunc;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.click = function (clickFunc) {\n\t\t\tif (!arguments.length) return click;\n\t\t\tclick = clickFunc;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.scroll = function (scrollFunc) {\n\t\t\tif (!arguments.length) return scroll;\n\t\t\tscroll = scrollFunc;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.colors = function (colorFormat) {\n\t\t\tif (!arguments.length) return colorCycle;\n\t\t\tcolorCycle = colorFormat;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.beginning = function (b) {\n\t\t\tif (!arguments.length) return beginning;\n\t\t\tbeginning = b;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.ending = function (e) {\n\t\t\tif (!arguments.length) return ending;\n\t\t\tending = e;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.labelMargin = function (m) {\n\t\t\tif (!arguments.length) return labelMargin;\n\t\t\tlabelMargin = m;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.labelFloat = function (f) {\n\t\t\tif (!arguments.length) return labelFloat;\n\t\t\tlabelFloat = f;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.rotateTicks = function (degrees) {\n\t\t\tif (!arguments.length) return rotateTicks;\n\t\t\trotateTicks = degrees;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.stack = function () {\n\t\t\tstacked = !stacked;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.relativeTime = function() {\n\t\t\ttimeIsRelative = !timeIsRelative;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.linearTime = function() {\n\t\t\ttimeIsLinear = !timeIsLinear;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.showBorderLine = function () {\n\t\t\tshowBorderLine = !showBorderLine;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.showBorderFormat = function(borderFormat) {\n\t\t\tif (!arguments.length) return showBorderFormat;\n\t\t\tshowBorderFormat = borderFormat;\n\t\t\treturn timelines;\n\t\t};\n\n\t\t// CSS class for the lines added by showBorder\n\t\ttimelines.showBorderLineClass = function(borderClass) {\n\t\t\tif (!arguments.length) return showBorderLineClass;\n\t\t\tshowBorderLineClass = borderClass;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.showToday = function () {\n\t\t\tshowTodayLine = !showTodayLine;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.showTodayFormat = function(todayFormat) {\n\t\t\tif (!arguments.length) return showTodayFormat;\n\t\t\tshowTodayFormat = todayFormat;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.colorProperty = function(colorProp) {\n\t\t\tif (!arguments.length) return colorPropertyName;\n\t\t\tcolorPropertyName = colorProp;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.rowSeparators = function (color) {\n\t\t\tif (!arguments.length) return rowSeparatorsColor;\n\t\t\trowSeparatorsColor = color;\n\t\t\treturn timelines;\n\n\t\t};\n\n\t\ttimelines.background = function (color) {\n\t\t\tif (!arguments.length) return backgroundColor;\n\t\t\tbackgroundColor = color;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.showTimeAxis = function () {\n\t\t\tshowTimeAxis = !showTimeAxis;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.showAxisTop = function () {\n\t\t\tshowAxisTop = !showAxisTop;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.showAxisCalendarYear = function () {\n\t\t\tshowAxisCalendarYear = !showAxisCalendarYear;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.showTimeAxisTick = function () {\n\t\t\ttimeAxisTick = !timeAxisTick;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.fullLengthBackgrounds = function () {\n\t\t\tfullLengthBackgrounds = !fullLengthBackgrounds;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.showTimeAxisTickFormat = function(format) {\n\t\t\tif (!arguments.length) return timeAxisTickFormat;\n\t\t\ttimeAxisTickFormat = format;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.showAxisHeaderBackground = function(bgColor) {\n\t\t\tshowAxisHeaderBackground = !showAxisHeaderBackground;\n\t\t\tif(bgColor) { (axisBgColor = bgColor); }\n\t\t\treturn timelines;\n\t\t};\n\n\t\t// CSS class for the x-axis\n\t\ttimelines.xAxisClass = function (axisClass) {\n\t\t\tif (!arguments.length) return xAxisClass;\n\t\t\txAxisClass = axisClass;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.navigate = function (navigateBackwards, navigateForwards) {\n\t\t\tif (!arguments.length) return [navigateLeft, navigateRight];\n\t\t\tnavigateLeft = navigateBackwards;\n\t\t\tnavigateRight = navigateForwards;\n\t\t\tshowAxisNav = !showAxisNav;\n\t\t\treturn timelines;\n\t\t};\n\n\t\ttimelines.version = function() {\n\t\t\treturn \"1.0.0\";\n\t\t};\n\n\t\treturn timelines;\n};\n\nexport default timelines;\n"
  },
  {
    "path": "test/timeline-test.js",
    "content": "var tape = require(\"tape\"),\n\td3 = Object.assign({}, require(\"../\"), require(\"d3\")),\n    timelines = require(\"../\");\n\ntape(\"timeline() returns the correct version\", function(test) {\n  test.equal(timelines.timelines().version(), '1.0.0');\n  test.end();\n});\n"
  }
]