           (.append "line"))
       (-> axis-container
           (.append "g")
-          (.attr "class" "y-axis axis")))))
+          (.attr "class" "y-axis positive axis"))
+      (-> axis-container
+          (.append "g")
+          (.attr "class" "y-axis negative axis")))))
 
 (defn chartable-builds [builds]
   (->> builds

                         (.enter)
                         (.append "g")
                         (.attr "class" "bar-pair"))
        grid-y-vals (for [tick (remove zero? y-tick-values)] (y-scale tick))
        grid-lines-join (-> svg
                            (.select "g.grid-lines")
                            (.selectAll "line.horizontal")
                            (.data (clj->js grid-y-vals)))]

    ;; top bar enter
    (-> bars-enter-g

                    "y" #(y-pos-scale (aget % "build_time_minutes"))
                    "x" #(x-scale (aget % "build_num"))
                    "width" (.rangeBand x-scale)
                    "height" #(- y-zero (y-pos-scale (aget % "build_time_minutes")))})
        (.select "title")
        (.text #(gstring/format "%s in %.1fm" (gstring/toTitleCase (aget % "outcome")) (aget % "build_time_minutes"))))

    ;; bottom bar enter and update
    (-> bars-join
        (.select ".bottom")
        (.attr #js {"y" y-zero
                    "x" #(x-scale (aget % "build_num"))
                    "width" (.rangeBand x-scale)
                    "height" #(- (y-neg-scale (aget % "queued_time_millis")) y-zero)})
        (.select "title")
        (.text #(gstring/format "Queue time %.1fm" (aget % "queued_time_millis"))))

    ;; bars exit
    (-> bars-join
