Permalink
Browse files

mouse stuff added

  • Loading branch information...
1 parent 0183d8e commit 50ec27e72d86959e16e07ed4fda4162c1c4afd56 @vogievetsky committed Jun 30, 2011
Showing with 614 additions and 37 deletions.
  1. +186 −0 docs/docco.css
  2. +107 −16 dvl.coffee
  3. +152 −21 dvl.js
  4. +169 −0 examples/time/mouse.html
View
@@ -0,0 +1,186 @@
+/*--------------------- Layout and Typography ----------------------------*/
+body {
+ font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
+ font-size: 15px;
+ line-height: 22px;
+ color: #252519;
+ margin: 0; padding: 0;
+}
+a {
+ color: #261a3b;
+}
+ a:visited {
+ color: #261a3b;
+ }
+p {
+ margin: 0 0 15px 0;
+}
+h1, h2, h3, h4, h5, h6 {
+ margin: 0px 0 15px 0;
+}
+ h1 {
+ margin-top: 40px;
+ }
+#container {
+ position: relative;
+}
+#background {
+ position: fixed;
+ top: 0; left: 525px; right: 0; bottom: 0;
+ background: #f5f5ff;
+ border-left: 1px solid #e5e5ee;
+ z-index: -1;
+}
+#jump_to, #jump_page {
+ background: white;
+ -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
+ -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
+ font: 10px Arial;
+ text-transform: uppercase;
+ cursor: pointer;
+ text-align: right;
+}
+#jump_to, #jump_wrapper {
+ position: fixed;
+ right: 0; top: 0;
+ padding: 5px 10px;
+}
+ #jump_wrapper {
+ padding: 0;
+ display: none;
+ }
+ #jump_to:hover #jump_wrapper {
+ display: block;
+ }
+ #jump_page {
+ padding: 5px 0 3px;
+ margin: 0 0 25px 25px;
+ }
+ #jump_page .source {
+ display: block;
+ padding: 5px 10px;
+ text-decoration: none;
+ border-top: 1px solid #eee;
+ }
+ #jump_page .source:hover {
+ background: #f5f5ff;
+ }
+ #jump_page .source:first-child {
+ }
+table td {
+ border: 0;
+ outline: 0;
+}
+ td.docs, th.docs {
+ max-width: 450px;
+ min-width: 450px;
+ min-height: 5px;
+ padding: 10px 25px 1px 50px;
+ overflow-x: hidden;
+ vertical-align: top;
+ text-align: left;
+ }
+ .docs pre {
+ margin: 15px 0 15px;
+ padding-left: 15px;
+ }
+ .docs p tt, .docs p code {
+ background: #f8f8ff;
+ border: 1px solid #dedede;
+ font-size: 12px;
+ padding: 0 0.2em;
+ }
+ .pilwrap {
+ position: relative;
+ }
+ .pilcrow {
+ font: 12px Arial;
+ text-decoration: none;
+ color: #454545;
+ position: absolute;
+ top: 3px; left: -20px;
+ padding: 1px 2px;
+ opacity: 0;
+ -webkit-transition: opacity 0.2s linear;
+ }
+ td.docs:hover .pilcrow {
+ opacity: 1;
+ }
+ td.code, th.code {
+ padding: 14px 15px 16px 25px;
+ width: 100%;
+ vertical-align: top;
+ background: #f5f5ff;
+ border-left: 1px solid #e5e5ee;
+ }
+ pre, tt, code {
+ font-size: 12px; line-height: 18px;
+ font-family: Monaco, Consolas, "Lucida Console", monospace;
+ margin: 0; padding: 0;
+ }
+
+
+/*---------------------- Syntax Highlighting -----------------------------*/
+td.linenos { background-color: #f0f0f0; padding-right: 10px; }
+span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
+body .hll { background-color: #ffffcc }
+body .c { color: #408080; font-style: italic } /* Comment */
+body .err { border: 1px solid #FF0000 } /* Error */
+body .k { color: #954121 } /* Keyword */
+body .o { color: #666666 } /* Operator */
+body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
+body .cp { color: #BC7A00 } /* Comment.Preproc */
+body .c1 { color: #408080; font-style: italic } /* Comment.Single */
+body .cs { color: #408080; font-style: italic } /* Comment.Special */
+body .gd { color: #A00000 } /* Generic.Deleted */
+body .ge { font-style: italic } /* Generic.Emph */
+body .gr { color: #FF0000 } /* Generic.Error */
+body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+body .gi { color: #00A000 } /* Generic.Inserted */
+body .go { color: #808080 } /* Generic.Output */
+body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+body .gs { font-weight: bold } /* Generic.Strong */
+body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+body .gt { color: #0040D0 } /* Generic.Traceback */
+body .kc { color: #954121 } /* Keyword.Constant */
+body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
+body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
+body .kp { color: #954121 } /* Keyword.Pseudo */
+body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
+body .kt { color: #B00040 } /* Keyword.Type */
+body .m { color: #666666 } /* Literal.Number */
+body .s { color: #219161 } /* Literal.String */
+body .na { color: #7D9029 } /* Name.Attribute */
+body .nb { color: #954121 } /* Name.Builtin */
+body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
+body .no { color: #880000 } /* Name.Constant */
+body .nd { color: #AA22FF } /* Name.Decorator */
+body .ni { color: #999999; font-weight: bold } /* Name.Entity */
+body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+body .nf { color: #0000FF } /* Name.Function */
+body .nl { color: #A0A000 } /* Name.Label */
+body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+body .nt { color: #954121; font-weight: bold } /* Name.Tag */
+body .nv { color: #19469D } /* Name.Variable */
+body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+body .w { color: #bbbbbb } /* Text.Whitespace */
+body .mf { color: #666666 } /* Literal.Number.Float */
+body .mh { color: #666666 } /* Literal.Number.Hex */
+body .mi { color: #666666 } /* Literal.Number.Integer */
+body .mo { color: #666666 } /* Literal.Number.Oct */
+body .sb { color: #219161 } /* Literal.String.Backtick */
+body .sc { color: #219161 } /* Literal.String.Char */
+body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
+body .s2 { color: #219161 } /* Literal.String.Double */
+body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+body .sh { color: #219161 } /* Literal.String.Heredoc */
+body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+body .sx { color: #954121 } /* Literal.String.Other */
+body .sr { color: #BB6688 } /* Literal.String.Regex */
+body .s1 { color: #219161 } /* Literal.String.Single */
+body .ss { color: #19469D } /* Literal.String.Symbol */
+body .bp { color: #954121 } /* Name.Builtin.Pseudo */
+body .vc { color: #19469D } /* Name.Variable.Class */
+body .vg { color: #19469D } /* Name.Variable.Global */
+body .vi { color: #19469D } /* Name.Variable.Instance */
+body .il { color: #666666 } /* Literal.Number.Integer.Long */
View
@@ -77,6 +77,16 @@ dvl.util = {
maxIdx = i
return { min, max, minIdx, maxIdx }
+
+
+ getRow: (data, i) ->
+ if dvl.typeOf(data) is 'array'
+ return data[i]
+ else
+ row = {}
+ for k,vs of data
+ row[k] = vs[i]
+ return row
}
(->
@@ -197,7 +207,7 @@ dvl.util = {
null
shift: ->
# TODO: make prev work
- @val = @value.shift()
+ val = @value.shift()
@changed = true
return val
get: ->
@@ -603,7 +613,8 @@ dvl.zero = dvl.const(0, 'zero')
dvl.null = dvl.const(null, 'null')
-dvl.identity = dvl.const(((x) -> x), 'identity')
+dvl.ident = (x) -> x
+dvl.identity = dvl.const(dvl.ident, 'identity')
dvl.acc = (c) ->
@@ -863,14 +874,18 @@ dvl.json2 = (->
getError = (xhr, textStatus) ->
return if textStatus is "abort"
q = this.q
- if this.url is q.url.get()
- q.data = null
- q.onError(textStatus) if q.onError
+ url = this.url
+ request = this.request
+ setTimeout((->
+ if url is q.url.get()
+ q.data = null
+ q.onError(textStatus) if q.onError
- q.status = 'ready'
- q.curAjax = null
+ q.status = 'ready'
+ q.curAjax = null
- maybeDone(this.request)
+ maybeDone(request)
+ ), 1)
makeRequest = (q, request) ->
q.status = 'requesting'
@@ -888,7 +903,7 @@ dvl.json2 = (->
else
setTimeout((->
getData.call(ctx, null)
- ), 10)
+ ), 1)
inputChange = ->
bundle = []
@@ -1044,8 +1059,8 @@ dvl.resizer = (sizeRef, marginRef, options) ->
if options.height
fh = if dvl.typeOf(options.height) is 'function' then options.height else dvl.identity
else
- fw = ident
- fh = ident
+ fw = dvl.ident
+ fh = dvl.ident
onResize = ->
margin = if marginRef then marginRef.get() else marginDefault
@@ -1110,7 +1125,44 @@ dvl.format = (string, subs) ->
dvl.register({fn:makeString, listen:list, change:[out], name:'formater'})
return out
+
+dvl.snap = ({data, acc, value, name}) ->
+ throw 'No data given' unless data
+ acc = dvl.wrapConstIfNeeded(acc or dvl.identity)
+ value = dvl.wrapConstIfNeeded(value)
+ name or= 'snaped_data'
+ out = dvl.def(null, name)
+
+ updateSnap = ->
+ ds = data.get()
+ a = acc.get()
+ v = value.get()
+
+ if ds and a and v
+ if dvl.typeOf(ds) isnt 'array'
+ # ToDo: make this nicer
+ dsc = a(ds)
+ a = (x) -> x
+
+ minDist = Infinity
+ minIdx = -1
+ for d,i in dsc
+ dist = Math.abs(a(d) - v)
+ if dist < minDist
+ minDist = dist
+ minIdx = i
+
+ minDatum = if minIdx < 0 then null else dvl.util.getRow(ds, minIdx)
+ out.set(minDatum) unless out.get() is minDatum
+ else
+ out.set(null)
+ dvl.notify(out)
+
+ dvl.register({fn:updateSnap, listen:[data, acc, value], change:[out], name:name+'_maker'})
+ return out
+
+
dvl.hasher = (obj) ->
updateHash = ->
h = obj.get()
@@ -1381,6 +1433,30 @@ dvl.gen.fromFn = (fn) ->
gen.setGen(fn, Infinity)
return gen
+dvl.gen.fromValue = (value, acc, fn) ->
+ value = dvl.wrapConstIfNeeded(value)
+ acc = dvl.wrapConstIfNeeded(acc or dvl.identity)
+ fn = dvl.wrapConstIfNeeded(fn or dvl.identity)
+
+ gen = dvl.def(null, 'value_generator')
+
+ makeGen = ->
+ a = acc.get()
+ f = fn.get()
+ v = value.get()
+ if a? and f? and v?
+ rv = f(a(v))
+ g = -> rv
+
+ gen.setGen(g)
+ else
+ gen.setGen(null)
+
+ dvl.notify(gen)
+
+ dvl.register({fn:makeGen, listen:[value, acc, fn], change:[gen], name:'value_make_gen'})
+ return gen
+
dvl.gen.fromArray = (data, acc, fn) ->
data = dvl.wrapConstIfNeeded(data)
acc = dvl.wrapConstIfNeeded(acc or dvl.identity)
@@ -1734,27 +1810,37 @@ dvl.svg = {}
height: pHeight
- dvl.svg.mouse = (panel) ->
+ dvl.svg.mouse = ({panel, fnX, fnY, flipX, flipY}) ->
+ fnX = dvl.wrapConstIfNeeded(fnX or dvl.identity)
+ fnY = dvl.wrapConstIfNeeded(fnY or dvl.identity)
+ flipX = dvl.wrapConstIfNeeded(flipX or false)
+ flipY = dvl.wrapConstIfNeeded(flipY or false)
+
x = dvl.def(null, 'mouse_x')
y = dvl.def(null, 'mouse_y')
+ lastMouse = [-1, -1]
recorder = ->
- m = d3.svg.mouse(panel.g.node())
+ m = lastMouse = if d3.event then d3.svg.mouse(panel.g.node()) else lastMouse
w = panel.width.get()
h = panel.height.get()
+ fx = fnX.get()
+ fy = fnY.get()
mx = m[0]
my = m[1]
if 0 <= mx <= w and 0 <= my <= h
- x.set(mx)
- y.set(my)
+ mx = w-mx if flipX.get()
+ my = h-my if flipY.get()
+ x.set(fx(mx)) if fx
+ y.set(fy(my)) if fy
else
x.set(null)
y.set(null)
dvl.notify(x, y)
panel.g.on('mousemove', recorder).on('mouseout', recorder)
-
+ dvl.register({ fn:recorder, listen:[fnX, fnY, flipX, flipY], change:[x, y], name:'mouse_recorder' })
return { x, y }
@@ -2673,6 +2759,11 @@ dvl.html.table.renderer =
sel.enter('div').attr('class', 'bar_div').style('width', ((d) -> dataFn(d) + 'px'))
sel.style('width', ((d) -> dataFn(d) + 'px'))
null
+ img: (col, dataFn) ->
+ sel = col.selectAll('img').data((d) -> [d])
+ sel.enter('img').attr('src', dataFn)
+ sel.attr('src', dataFn)
+ null
svgSparkline: ({classStr, width, height, x, y, padding}) -> (col, dataFn) ->
svg = col.selectAll('svg').data((i) -> [dataFn(i)])
Oops, something went wrong.

0 comments on commit 50ec27e

Please sign in to comment.