How fast does your browser render line charts?

by juve

HTML

<script src="http://coffeescript.org/v1/browser-compiler/coffee-script.js"></script>
<linedemo unresolved>
  <template>
    <!--<button class="tab-button"><content select="name"></content></button>-->
    <content></content>
  </template>

  <tabs>
  </tabs>

  <app name="Lines" id="line-render-app" autostart>
    <!--<name>Lines!</name>-->
    <template>
      <canvas width="400" height=200></canvas>
      <controls>
        <inputs ng-enter="render">
          <label>lines:</label><input type="text" ng-model="lineCount"></input>
          <label>t<sub>max</sub>:</label><input type="text" ng-model="t_max"></input>
          <label></label><button ng-click="render">render</button>
          <label></label><button ng-click="render(,true)">render (sync)</button>
        </inputs>
        <stats>
          <label>t<sub>create</sub></label><span> = </span><span ng-text="t_create"></span><span> ms</span>
          <label>t<sub>pack</sub></label><span> = </span><span ng-text="t_pack"></span><span> ms</span>
          <label>t<sub>unpack</sub></label><span> = </span><span ng-text="t_unpack"></span><span> ms</span>
          <label>t<sub>render</sub></label><span> = </span><span ng-text="t_render"></span><span> ms</span>
        </stats>
      </controls>
      <script type="text/coffeescript">
          #imports
          {SVGCOLORS} = window

          #setup global scope
          G = this

          #setup scope for DOM interaction
          G.O = {}

          #basic utils
          G.warn     ?= (a...) -> console.debug a...
          G.$        ?= (a...) -> document.querySelectorAll a...
          G.isString ?= (s)    -> typeof s is "string"
          G.isEmpty  ?= (s)    -> (not s?) or s == ""

          #setup document root
          G.document ?= document
          if G.document == document then G.warn "You are running as root. Be careful!", G.document

          #wrap global jQuery locally
          G.$ = do -> jQuery = window.$; (o,a...) ->
            if...

CSS

linedemo canvas {
  border: solid 1px silver;
}
linedemo > * {
  float: left;
  clear: left;
}
linedemo controls > * {
  float: left;
}
linedemo span,linedemo input,linedemo button,linedemo p,linedemo label {
  font-family: BentonSans, Benton Sans, News Gothic MT, News Gothic, Verdana, sans;
  font-size: 10pt;
}
linedemo inputs {
  padding-left: 3px;
}
linedemo inputs > input {
  float: left;
}
linedemo inputs > label {
  margin-top: 8px;
  float: left;
  clear: left;
  min-width: 35px;
}
linedemo inputs > button {
  float: left;
}
linedemo stats {
  padding-left: 5px;
  border: solid 1px silver;
}
linedemo stats > label {
  clear: left;
}
stats > * {
  float: left;
}
linedemo stats > span {
  white-space: pre;
}
linedemo label {
  display: block;
  color: gray;
  float: left;
  min-width: 50px;
}
linedemo input,linedemo button,linedemo ul {
  padding: 1px;
  margin: 1px;
}
linedemo input,linedemo button {
  height: 30px;
}

CoffeeScript

if window.angular_poc_loaded then return
window.angular_poc_loaded = true

do ->
    
    doc = document; warn = window.warn ?= (a...) -> console.log a...
    loadTemplate = (sel) -> doc.importNode doc.querySelector(sel).content,true
    loadFirst = null

    fns = []

    run = -> if fn = fns.shift() then fn run

    runScript = (code,scope) ->
      Function(CoffeeScript.compile(code,bare:true)).apply(scope)

    runScriptLater = (code,scope) ->
      fns.push (cb) -> runScript code, scope; cb()

    loadScript = (src,scope) ->
      fns.push (cb) ->
        r = new window.XMLHttpRequest
        r.open('GET',src, true)
        r.overrideMimeType('text/plain')
        r.onreadystatechange = -> if 4 == r.readyState
          if r.status in [0,200] then runScript r.responseText, scope
          else throw new Error "Script not loaded" + src
          cb()
        r.send()

    applyTemplate = (tpl,trg,content) ->
      trg = $(trg).append loadTemplate tpl
      for t in trg.find("content[select]")
        select = $(t).attr "select"
        match  = $(content).find(select)
        $(t).replaceWith match.contents() if match.length > 0
        match.remove()
      trg.find("content").replaceWith content if content?
      scope = document:trg
      for t in trg.find("script[type='text/coffeescript']")
        src = $(t).attr "src"
        warn src:src
        if src == "" or not src? then runScriptLater $(t).text(), scope
        else                          loadScript src, scope
      run()
      trg

    do ->
      tabs = $("tabs")
      apps = $("app")
      tpl  = "linedemo>template"
      apps.each ->
        name = $(@).attr("name"); autostart = $(@).attr "autostart"
        console.log name, tabs
        id = @id; warn {name,id,autostart}
        tab = applyTemplate tpl, $("<tab>"), app = @
        tab.find(".tab-button").click fn = ->
          warn "loading app",name,app_tpl = "##{id}>template"
          applyTemplate app_tpl,app

        $(tabs).append...