Started work on pre-computing geometry, to allow shuffling labels.
This commit is contained in:
parent
b75d7f8839
commit
b9d98957eb
|
@ -10,6 +10,13 @@
|
||||||
|
|
||||||
(def ^:dynamic *foreground* "black")
|
(def ^:dynamic *foreground* "black")
|
||||||
|
|
||||||
|
;; TODO: Right, so most of this is good. But I need to adjust the positions
|
||||||
|
;; of minor segment labels -- by sliding some of them sideways -- before
|
||||||
|
;; rendering. So probably what I need to do is one pass through the data
|
||||||
|
;; structure, tagging each node with geometry information (especially for
|
||||||
|
;; minor segment labels); then a second pass to sort out spacial collisions;
|
||||||
|
;; and don't try to generate the SVG until that has been done. But I need
|
||||||
|
;; *all* the geometry to be complete.
|
||||||
|
|
||||||
(defn polar-to-cartesian
|
(defn polar-to-cartesian
|
||||||
"Return, as a map with keys :x. :y, the cartesian coordinates at the point
|
"Return, as a map with keys :x. :y, the cartesian coordinates at the point
|
||||||
|
@ -44,18 +51,27 @@
|
||||||
(defn- font-size [thickness]
|
(defn- font-size [thickness]
|
||||||
(int (* 0.15 thickness)))
|
(int (* 0.15 thickness)))
|
||||||
|
|
||||||
|
(defn left-half?
|
||||||
|
[datum]
|
||||||
|
(> (+ (:left datum) (:right datum)) 1))
|
||||||
|
|
||||||
|
(defn- label-width
|
||||||
|
"Return the anticipated width of the label associated with this `datum`."
|
||||||
|
[datum thickness]
|
||||||
|
(* (count (:label datum)) (font-size thickness)))
|
||||||
|
|
||||||
(defn- text-path [datum tp-id geometry thickness start-angle end-angle]
|
(defn- text-path [datum tp-id geometry thickness start-angle end-angle]
|
||||||
[:path {:class "rsvggraph-text-path"
|
[:path {:class "rsvggraph-text-path"
|
||||||
:id tp-id
|
:id tp-id
|
||||||
:style {:fill "none"
|
:style {:fill "none"
|
||||||
:stroke "none"}
|
:stroke "none"}
|
||||||
:d (let [angle (if (> (+ start-angle end-angle) 360) start-angle end-angle)
|
:d (let [angle (if (left-half? datum) start-angle end-angle)
|
||||||
radius (:radius geometry)
|
radius (:radius geometry)
|
||||||
end (polar-to-cartesian (assoc geometry :radius (* 1.2 (:radius geometry)) :angle angle))
|
end (polar-to-cartesian (assoc geometry :radius (* 1.2 (:radius geometry)) :angle angle))
|
||||||
height (int (:y end))]
|
height (int (:y end))]
|
||||||
(if (minor-segment? datum)
|
(if (minor-segment? datum)
|
||||||
(if (> angle 180)
|
(if (left-half? datum)
|
||||||
(format "M %d %d L %d %d" (- (int (:x end)) (* (count (:label datum)) (font-size thickness))) height
|
(format "M %d %d L %d %d" (- (int (:x end)) (label-width datum thickness)) height
|
||||||
(int (:x end)) height)
|
(int (:x end)) height)
|
||||||
(format "M %d %d L %d %d" (int (:x end)) height (:width geometry) height))
|
(format "M %d %d L %d %d" (int (:x end)) height (:width geometry) height))
|
||||||
(describe-arc (assoc geometry :radius (- radius (* 0.9 thickness)))
|
(describe-arc (assoc geometry :radius (- radius (* 0.9 thickness)))
|
||||||
|
@ -70,7 +86,30 @@
|
||||||
|
|
||||||
(defn- label-indicator [datum geometry start-angle end-angle]
|
(defn- label-indicator [datum geometry start-angle end-angle]
|
||||||
(when (minor-segment? datum) [:path {:class "rsvggraph-minor-label-indicator" :style {:fill "none" :stroke *foreground* :stroke-width "thin"}
|
(when (minor-segment? datum) [:path {:class "rsvggraph-minor-label-indicator" :style {:fill "none" :stroke *foreground* :stroke-width "thin"}
|
||||||
:d (label-indicator-path geometry (if (> (+ start-angle end-angle) 360) start-angle end-angle))}]))
|
:d (label-indicator-path geometry (if (left-half? datum) start-angle end-angle))}]))
|
||||||
|
|
||||||
|
(defn segment-geometry
|
||||||
|
[datum geometry]
|
||||||
|
(let [thickness (/ (:radius geometry) (:ring datum))
|
||||||
|
left? (left-half? datum)
|
||||||
|
start-angle (* (:left datum) 360)
|
||||||
|
end-angle (* (:right datum) 360)
|
||||||
|
angle (if left? start-angle end-angle)
|
||||||
|
kink (polar-to-cartesian
|
||||||
|
(assoc geometry :radius (* 1.2 (:radius geometry)) :angle angle))
|
||||||
|
label-bottom (int (:y kink))]
|
||||||
|
(merge geometry
|
||||||
|
{:thickness thickness
|
||||||
|
:radius (- (:radius geometry) (/ thickness 2))
|
||||||
|
:start-angle start-angle
|
||||||
|
:end-angle end-angle
|
||||||
|
:text-box (when (minor-segment? datum)
|
||||||
|
{:left (if left? (- (int (:x kink)) (label-width datum thickness))
|
||||||
|
(int (:x kink)))
|
||||||
|
:right (if left? (int (:x kink))
|
||||||
|
(+ (int (:x kink)) (label-width datum thickness)))
|
||||||
|
:bottom label-bottom
|
||||||
|
:top (+ label-bottom (font-size datum))})})))
|
||||||
|
|
||||||
(defn draw-segment
|
(defn draw-segment
|
||||||
[datum geometry]
|
[datum geometry]
|
||||||
|
|
Loading…
Reference in a new issue