1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
|
{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
{- |
Module : Data.GraphViz.Attributes
Description : User-friendly wrappers around Graphviz attributes.
Copyright : (c) Matthew Sackman, Ivan Lazar Miljenovic
License : 3-Clause BSD-style
Maintainer : Ivan.Miljenovic@gmail.com
There are almost 150 possible attributes available for Dot graphs, and
it can be difficult to know which ones to use. This module provides
helper functions for the most commonly used ones.
The complete list of all possible attributes can be found in
"Data.GraphViz.Attributes.Complete"; it is possible to use both of
these modules if you require specific extra attributes that are not
provided here.
-}
module Data.GraphViz.Attributes
( -- * The definition of attributes
Attribute
, Attributes
-- * Creating labels
-- $labels
, toLabel
, textLabel
, xLabel
, xTextLabel
, forceLabels
, textLabelValue
, Labellable(..)
-- * Colors
-- $colors
, X11Color(..)
, bgColor
, bgColors
, fillColor
, fillColors
, fontColor
, penColor
, color
-- * Stylistic attributes
-- $styles
, penWidth
, gradientAngle
, style
, styles
, Style
, dashed
, dotted
, solid
, bold
, invis
, filled
, diagonals
, striped
, wedged
, rounded
, tapered
, radial
-- * Node shapes
, shape
, Shape(..)
-- * Edge arrows
, arrowTo
, arrowFrom
-- ** Specifying where to draw arrows on an edge.
, edgeEnds
, DirType(..)
-- ** Default arrow types.
, Arrow
-- *** The 9 primitive arrows.
, box
, crow
, diamond
, dotArrow
, inv
, noArrow
, normal
, tee
, vee
-- *** 5 derived arrows.
, oDot
, invDot
, invODot
, oBox
, oDiamond
-- * Layout
, ordering
, Order(..)
, rank
, RankType(..)
) where
import Data.GraphViz.Attributes.Arrows
import Data.GraphViz.Attributes.Colors
import Data.GraphViz.Attributes.Colors.X11
import Data.GraphViz.Attributes.Complete (Attribute (..),
Attributes)
import qualified Data.GraphViz.Attributes.HTML as Html
import Data.GraphViz.Attributes.Internal
import Data.GraphViz.Attributes.Values
import qualified Data.Text as ST
import Data.Text.Lazy (Text)
import qualified Data.Text.Lazy as T
-- -----------------------------------------------------------------------------
{- $labels
The following escape codes are available for labels (where applicable):
[@\\N@] Replace with the name of the node.
[@\\G@] Replace with the name of the graph (for node attributes)
or the name of the graph or cluster, whichever is
applicable (for graph, cluster and edge attributes).
[@\\E@] Replace with the name of the edge, formed by the two
adjoining nodes and the edge type.
[@\\T@] Replace with the name of the node the edge is coming from.
[@\\H@] Replace with the name of the node the edge is going to.
[@\\n@] Centered newline.
[@\\l@] Left-justified newline.
[@\\r@] Right-justified newline.
-}
-- | A convenience class to make it easier to create labels. It is
-- highly recommended that you make any other types that you wish to
-- create labels from an instance of this class, preferably via the
-- @String@ or @Text@ instances.
class Labellable a where
-- | This function only creates a 'Label' value to enable you to use
-- it for 'Attributes' such as 'HeadLabel', etc.
toLabelValue :: a -> Label
-- | Equivalent to @'Label' . 'toLabelValue'@; the most common label
-- 'Attribute'.
toLabel :: (Labellable a) => a -> Attribute
toLabel = Label . toLabelValue
-- | An alias for 'toLabel' for use with the @OverloadedStrings@
-- extension.
textLabel :: Text -> Attribute
textLabel = toLabel
-- | Create a label /outside/ of a node\/edge. Currently only in the
-- Graphviz development branch (2.29.*).
xLabel :: (Labellable a) => a -> Attribute
xLabel = XLabel . toLabelValue
-- | An alias for 'xLabel' for use with the @OverloadedStrings@ extension.
xTextLabel :: Text -> Attribute
xTextLabel = xLabel
-- | Force the positioning of 'xLabel's, even when it will cause overlaps.
forceLabels :: Attribute
forceLabels = ForceLabels True
-- | An alias for 'toLabelValue' for use with the @OverloadedStrings@
-- extension.
textLabelValue :: Text -> Label
textLabelValue = toLabelValue
instance Labellable Text where
toLabelValue = StrLabel
instance Labellable ST.Text where
toLabelValue = toLabelValue . T.fromStrict
instance Labellable Char where
toLabelValue = toLabelValue . T.singleton
instance Labellable String where
toLabelValue = toLabelValue . T.pack
instance Labellable Int where
toLabelValue = toLabelValue . show
instance Labellable Double where
toLabelValue = toLabelValue . show
instance Labellable Bool where
toLabelValue = toLabelValue . show
instance Labellable Html.Label where
toLabelValue = HtmlLabel
instance Labellable Html.Text where
toLabelValue = toLabelValue . Html.Text
instance Labellable Html.Table where
toLabelValue = toLabelValue . Html.Table
instance Labellable RecordFields where
toLabelValue = RecordLabel
instance Labellable RecordField where
toLabelValue = toLabelValue . (:[])
-- | A shorter variant than using @PortName@ from 'RecordField'.
instance Labellable PortName where
toLabelValue = toLabelValue . PortName
-- | A shorter variant than using 'LabelledTarget'.
instance Labellable (PortName, EscString) where
toLabelValue = toLabelValue . uncurry LabelledTarget
-- -----------------------------------------------------------------------------
{- $colors
The recommended way of dealing with colors in Dot graphs is to use the
named 'X11Color's rather than explicitly specifying RGB, RGBA or HSV
colors.
These functions also allow you to use SVG and Brewer colors, but
X11 colors are generally preferable. If you wish to use SVG
colors, either import this module hiding 'X11Color' or import the
SVG module qualified.
-}
-- | Specify the background color of a graph or cluster. For
-- clusters, if @'style' 'filled'@ is used, then 'fillColor' will
-- override it.
bgColor :: (NamedColor nc) => nc -> Attribute
bgColor = BgColor . toColorList . (:[]) . toColor
-- | As with 'bgColor', but add a second color to create a gradient
-- effect. Requires Graphviz >= 2.29.0.
bgColors :: (NamedColor nc) => nc -> nc -> Attribute
bgColors c1 c2 = BgColor . toColorList $ map toColor [c1,c2]
-- | Specify the fill color of a node, cluster or arrowhead. Requires
-- @'style' 'filled'@ for nodes and clusters. For nodes and edges,
-- if this isn't set then the 'color' value is used instead; for
-- clusters, 'bgColor' is used.
fillColor :: (NamedColor nc) => nc -> Attribute
fillColor = FillColor . toColorList . (:[]) . toColor
-- | As with 'fillColor', but add a second color to create a gradient
-- effect. Requires Graphviz >= 2.29.0.
fillColors :: (NamedColor nc) => nc -> nc -> Attribute
fillColors c1 c2 = FillColor . toColorList $ map toColor [c1,c2]
-- | Specify the color of text.
fontColor :: (NamedColor nc) => nc -> Attribute
fontColor = FontColor . toColor
-- | Specify the color of the bounding box of a cluster.
penColor :: (NamedColor nc) => nc -> Attribute
penColor = PenColor . toColor
-- | The @color@ attribute serves several purposes. As such care must
-- be taken when using it, and it is preferable to use those
-- alternatives that are available when they exist.
--
-- * The color of edges;
--
-- * The bounding color of nodes;
--
-- * The bounding color of clusters (i.e. equivalent to 'penColor');
--
-- * If the 'filled' 'Style' is set, then it defines the
-- background color of nodes and clusters unless 'fillColor' or
-- 'bgColor' respectively is set.
color :: (NamedColor nc) => nc -> Attribute
color = Color . toColorList . (:[]) . toColor
-- -----------------------------------------------------------------------------
{- $styles
Various stylistic attributes to customise how items are drawn.
Unless specified otherwise, all 'Style's are available for nodes;
those specified also can be used for edges and clusters.
-}
-- | A particular style type to be used.
type Style = StyleItem
style :: Style -> Attribute
style = styles . (:[])
styles :: [Style] -> Attribute
styles = Style
-- | Also available for edges.
dashed :: Style
dashed = SItem Dashed []
-- | Also available for edges.
dotted :: Style
dotted = SItem Dotted []
-- | Also available for edges.
solid :: Style
solid = SItem Solid []
-- | Also available for edges.
invis :: Style
invis = SItem Invisible []
-- | Also available for edges.
bold :: Style
bold = SItem Bold []
-- | Also available for clusters.
filled :: Style
filled = SItem Filled []
-- | Also available for clusters.
rounded :: Style
rounded = SItem Rounded []
-- | Only available for nodes.
diagonals :: Style
diagonals = SItem Diagonals []
-- | Only available for rectangularly-shaped nodes and
-- clusters. Requires Graphviz >= 2.30.0.
striped :: Style
striped = SItem Striped []
-- | Only available for elliptically-shaped nodes. Requires Graphviz
-- >= 2.30.0.
wedged :: Style
wedged = SItem Wedged []
-- | Only available for edges; creates a tapered edge between the two
-- nodes. Requires Graphviz >= 2.29.0.
tapered :: Style
tapered = SItem Tapered []
-- | Available for nodes, clusters and edges. When using
-- 'gradientAngle', indicates that a radial gradient should be used.
-- Requires Graphviz >= 2.29.0.
radial :: Style
radial = SItem Radial []
-- | Specify the width of lines. Valid for clusters, nodes and edges.
penWidth :: Double -> Attribute
penWidth = PenWidth
-- | Specify the angle at which gradient fills are drawn; for use with
-- 'bgColors' and 'fillColors'. Requires Graphviz >= 2.29.0.
gradientAngle :: Int -> Attribute
gradientAngle = GradientAngle
-- -----------------------------------------------------------------------------
-- | The shape of a node.
shape :: Shape -> Attribute
shape = Shape
-- -----------------------------------------------------------------------------
-- | A particular way of drawing the end of an edge.
type Arrow = ArrowType
-- | How to draw the arrow at the node the edge is pointing to. For
-- an undirected graph, requires either @'edgeEnds' 'Forward'@ or
-- @'edgeEnds' 'Both'@.
arrowTo :: Arrow -> Attribute
arrowTo = ArrowHead
-- | How to draw the arrow at the node the edge is coming from.
-- Requires either @'edgeEnds' 'Back'@ or @'edgeEnds' 'Both'@.
arrowFrom :: Arrow -> Attribute
arrowFrom = ArrowTail
-- | Specify where to place arrows on an edge.
edgeEnds :: DirType -> Attribute
edgeEnds = Dir
box, crow, diamond, dotArrow, inv, noArrow, tee, vee :: Arrow
oDot, invDot, invODot, oBox, oDiamond :: Arrow
inv = AType [(noMods, Inv)]
dotArrow = AType [(noMods, DotArrow)]
invDot = AType [ (noMods, Inv)
, (noMods, DotArrow)]
oDot = AType [(ArrMod OpenArrow BothSides, DotArrow)]
invODot = AType [ (noMods, Inv)
, (openMod, DotArrow)]
noArrow = AType [(noMods, NoArrow)]
tee = AType [(noMods, Tee)]
diamond = AType [(noMods, Diamond)]
oDiamond = AType [(openMod, Diamond)]
crow = AType [(noMods, Crow)]
box = AType [(noMods, Box)]
oBox = AType [(openMod, Box)]
vee = AType [(noMods, Vee)]
-- -----------------------------------------------------------------------------
-- | Specify an ordering of edges of a node: either the outgoing or
-- the incoming edges of a node must appear left-to-right in the
-- same order in which they are defined in the input.
--
-- When specified as both a global graph or sub-graph level
-- attribute, then it takes precedence over an attribute specified
-- for an individual node.
ordering :: Order -> Attribute
ordering = Ordering
-- -----------------------------------------------------------------------------
-- | When using @dot@, this allows you to control relative placement
-- of sub-graphs and clusters.
rank :: RankType -> Attribute
rank = Rank
|