File: Attributes.hs

package info (click to toggle)
haskell-graphviz 2999.17.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,488 kB
  • sloc: haskell: 12,152; makefile: 2
file content (422 lines) | stat: -rw-r--r-- 12,612 bytes parent folder | download | duplicates (6)
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