Hylograph.Unified
- Package
- purescript-hylograph-selection
- Repository
- afcondon/purescript-hylograph-selection
PSD3.Unified - Unified Data DSL for Visualization and Computation
This module re-exports the unified DSL components, providing a single import for the new unified system.
Quick Start
import Hylograph.Unified
-- Define a computation that works in both viz and spreadsheet
growthAnalysis :: forall repr. DataDSL repr => repr (Array Number) -> repr Number
growthAnalysis data_ = avgA (mapA (\x -> x * 1.1) data_)
-- Use Display for formatting
myDisplay :: Display Number String
myDisplay = roundD 2 >>> showNumD >>> suffixD "%"
-- Create attributes with Display
myAttr :: Attribute DataPoint
myAttr = attr "cx" _.x (scaleD 10.0 >>> showNumD)
Module Organization
PSD3.Unified.DataDSL- Core type class for data operationsPSD3.Unified.Display- Profunctor-based display formattingPSD3.Unified.Attribute- Bridge to PSD3's attribute systemPSD3.Unified.Join- Composable join combinatorsPSD3.Unified.Sugar- Syntactic sugar operatorsPSD3.Unified.Interpreters.Eval- DataDSL instances for Eval/EvalD
Re-exports from Hylograph.Unified.Attribute
#transformD Source
transformD :: forall datum. (datum -> String) -> Attribute datumtransform attribute with display formatting
#toAttribute Source
toAttribute :: forall datum a. AttributeName -> (datum -> a) -> Display a String -> Attribute datumConvert a Display-based spec to an Attribute
This is useful when you have a Display and want to use it with existing attribute-based code.
#textContentD Source
textContentD :: forall datum a. (datum -> a) -> Display a String -> Attribute datumtext content with display formatting
#fromDisplay Source
fromDisplay :: forall a. AttributeName -> Display a String -> Attribute aCreate an attribute that just uses a Display for formatting
The extraction is identity - useful when datum is already the right type.
#attrStatic Source
attrStatic :: forall datum. String -> String -> Attribute datumCreate a static attribute (same for all data)
Example:
attrStatic "fill" "steelblue"
attrStatic "stroke-width" "2"
#attr Source
attr :: forall datum a. String -> (datum -> a) -> Display a String -> Attribute datumCreate an attribute from extraction function and display
This is the primary way to create attributes in the new style.
Example:
attr "cx" _.x (scaleD 10.0 >>> showNumD)
attr "fill" _.category idD
attr "opacity" _.importance (clampD 0.0 1.0 >>> showNumD)
Re-exports from Hylograph.Unified.DataDSL
#DataSource Source
data DataSource aData source - where data enters the computation pipeline
This is the "join point" - analogous to D3's selection.data()
Constructors
#DataDSL Source
class DataDSL :: (Type -> Type) -> Constraintclass DataDSL (repr :: Type -> Type) where
The unified data operations type class
This class captures the fundamental operations on data that are shared between visualization and spreadsheet contexts.
Key insight: These operations are exactly what D3 data joins do, and also what spreadsheet formulas do. They're the same thing!
Members
num :: Number -> repr Numberstr :: String -> repr StringString literal
bool :: Boolean -> repr BooleanBoolean literal
arr :: forall a. Array a -> repr (Array a)Array literal
source :: forall a. DataSource a -> repr (Array a)Data source - the "join point" where external data enters
In D3:
selection.data(arr)In spreadsheet: cell range reference likeA1:A10mapA :: forall a b. (a -> b) -> repr (Array a) -> repr (Array b)Map over array - the heart of D3 data joins
In D3: The template function in
.join("rect").attr("height", d => d.value)In spreadsheet:=MAP(A1:A10, x => x * 2)foldA :: forall a b. (b -> a -> b) -> b -> repr (Array a) -> repr bFold/reduce array to single value
In D3:
.data(arr).reduce((acc, d) => acc + d.value, 0)In spreadsheet:=SUM(A1:A10),=PRODUCT(B1:B5)filterA :: forall a. (a -> Boolean) -> repr (Array a) -> repr (Array a)Filter array by predicate
In D3:
.data(arr.filter(d => d.value > 0))In spreadsheet:=FILTER(A1:A10, x => x > 0)flatMapA :: forall a b. (a -> Array b) -> repr (Array a) -> repr (Array b)FlatMap - map then flatten (for nested data)
This is the
decomposein NestedJoin! In D3: Nested selections In spreadsheet:=FLATTEN(MAP(A1:A10, x => x.items))zipWithA :: forall a b c. (a -> b -> c) -> repr (Array a) -> repr (Array b) -> repr (Array c)Zip two arrays with combining function
headA :: forall a. repr (Array a) -> repr (Maybe a)Get first element
add :: repr Number -> repr Number -> repr NumberArithmetic operations (from NumExpr)
sub :: repr Number -> repr Number -> repr Numbermul :: repr Number -> repr Number -> repr Numberdiv :: repr Number -> repr Number -> repr Numbernegate :: repr Number -> repr Numberconcat :: repr String -> repr String -> repr StringString operations (from StringExpr)
lt :: repr Number -> repr Number -> repr BooleanComparison operations (from CompareExpr)
lte :: repr Number -> repr Number -> repr Booleangt :: repr Number -> repr Number -> repr Booleangte :: repr Number -> repr Number -> repr BooleaneqNum :: repr Number -> repr Number -> repr BooleanstrEq :: repr String -> repr String -> repr BooleanString comparison (from StringCompareExpr)
strNeq :: repr String -> repr String -> repr Booleanand :: repr Boolean -> repr Boolean -> repr BooleanBoolean operations (from BoolExpr)
or :: repr Boolean -> repr Boolean -> repr Booleannot :: repr Boolean -> repr BooleanifThenElse :: forall a. repr Boolean -> repr a -> repr a -> repr aConditional
#TrigDSL Source
class TrigDSL :: (Type -> Type) -> Constraintclass (DataDSL repr) <= TrigDSL repr where
Trigonometric operations - extension for visualization-specific math
Separated from DataDSL because spreadsheets rarely need trig, but polar/radial visualizations (chord diagrams, pie charts) do.
polarX :: forall repr. DataDSL repr => TrigDSL repr => repr Number -> repr Number -> repr Number
polarX r angle = r `mul` cos angle
Members
Re-exports from Hylograph.Unified.Display
#Display Source
newtype Display a bDisplay transformation from type a to type b
This is essentially a newtype around a -> b, but with a semantic
meaning: it's a non-destructive presentation transformation.
The profunctor structure (contravariant in a, covariant in b) enables flexible composition and adaptation.
Constructors
Display (a -> b)
#thousandsD Source
thousandsD :: Display String StringAdd thousands separators: 1234567 -> "1,234,567"
#runDisplay Source
runDisplay :: forall a b. Display a b -> a -> bRun a display transformation
#currencyWithSymbol Source
currencyWithSymbol :: String -> Display Number StringCurrency with custom symbol
#(>>>) Source
Operator alias for Hylograph.Unified.Display.composeD (left-associative / precedence 9)
Re-exports from Hylograph.Unified.Join
#PhaseSpec Source
type PhaseSpec datum = { attrs :: Array (Attribute datum), transition :: Maybe TransitionConfig }Configuration for a single GUP phase (enter, update, or exit)
attrs: Attributes to apply for this phasetransition: Optional animation configuration
#JoinSpec Source
data JoinSpec outer innerA join specification: data + template + config
The outer/inner type parameters allow type-changing joins. For simple joins where outer = inner, they'll be the same.
Constructors
JoinSpec { config :: JoinConfig outer inner, data_ :: Array outer, template :: inner -> Tree inner }
#JoinConfig Source
type JoinConfig outer inner = { decompose :: Maybe (Decomposer outer inner), gup :: Maybe (GUPSpec inner), key :: String, keyFn :: Maybe (inner -> String), name :: String }Full join configuration
This captures ALL the information needed to perform any kind of join, with optional decomposition and GUP behaviors.
#Decomposer Source
type Decomposer outer inner = outer -> Array innerA decomposer extracts inner data from outer data
Example: _.points :: SceneData -> Array DataPoint
#withGUP Source
withGUP :: forall outer inner. GUPSpec inner -> JoinSpec outer inner -> JoinSpec outer innerAdd GUP (General Update Pattern) behaviors to a join
GUP specifies enter/update/exit behaviors with optional transitions.
This replaces UpdateJoin.
join "circles" "circle" circleData $ \d -> ...
# withGUP
{ enter: Just { attrs: [opacity 0.0], transition: Just fadeIn }
, update: Just { attrs: [], transition: Just move }
, exit: Just { attrs: [opacity 0.0], transition: Just fadeOut }
}
#withDecompose Source
withDecompose :: forall outer inner. (outer -> Array inner) -> JoinSpec outer outer -> JoinSpec outer innerAdd decomposition to a join
Decomposition extracts inner data from outer data, enabling type changes.
This replaces NestedJoin.
join "rows" "tr" tableData identity
# withDecompose (_.cells) -- Extract cells from each row
Or with type change:
join "circles" "circle" [sceneData] identity
# withDecompose (_.points) -- SceneData -> Array DataPoint
#updateSpec Source
updateSpec :: forall datum. Array (Attribute datum) -> Maybe TransitionConfig -> PhaseSpec datumCreate an update phase specification
#toTree Source
toTree :: forall outer inner. JoinSpec outer inner -> Tree outerConvert a JoinSpec to a Tree (execute the join specification)
This is the final step - it produces the AST node that interpreters (D3, Mermaid, etc.) can process.
myTree :: Tree DataPoint
myTree = join "circles" "circle" dataPoints circleTemplate
# withGUP myGUP
# toTree
SAFETY: The unsafeCoerce calls in toTree are safe because:
Type erasure for existentials: PureScript lacks existential types, so we erase the inner datum type when storing decompose/template/gup functions. The functions were provided together at the call site (join/withDecompose/withGUP), guaranteeing they agree on the inner type.
outer = inner when no decompose: Without a decompose function, the join operates on outer directly (JoinSpec outer outer). The coercions are identity in this case.
AST stores erased types: The AST nodes (NestedJoin, UpdateNestedJoin) also use type erasure internally - they recover types via the stored functions at runtime.
#noTransition Source
noTransition :: forall datum. Array (Attribute datum) -> PhaseSpec datumPhase with no transition (immediate attribute application)
#join Source
join :: forall datum. String -> String -> Array datum -> (datum -> String) -> (datum -> Tree datum) -> JoinSpec datum datumCreate a basic join specification with key function
This is the foundation - data, a name, keyFn for identity, and a template. Decomposition and GUP can be added with combinators.
The key function extracts identity for matching in updates. This is mandatory because dynamic updates need stable identity matching.
join "nodes" "g" nodeData _.id $ \node ->
elem Group [...]
#buildJoin Source
buildJoin :: forall outer inner. JoinBuilder outer inner -> (inner -> Tree inner) -> JoinSpec outer innerBuild a join from a builder spec
This is the low-level API for full control.
Re-exports from Hylograph.Unified.Sugar
- Modules
- Data.
DependencyGraph - Hylograph.
AST - Hylograph.
Axis. Axis - Hylograph.
Brush - Hylograph.
Brush. FFI - Hylograph.
Brush. Types - Hylograph.
Classify - Hylograph.
Data. Graph - Hylograph.
Data. Graph. Algorithms - Hylograph.
Data. Node - Hylograph.
Data. Tree - Hylograph.
Expr. Animation - Hylograph.
Expr. Attr - Hylograph.
Expr. Datum - Hylograph.
Expr. Expr - Hylograph.
Expr. Friendly - Hylograph.
Expr. Integration - Hylograph.
Expr. Interpreter. CodeGen - Hylograph.
Expr. Interpreter. Eval - Hylograph.
Expr. Interpreter. Meta - Hylograph.
Expr. Interpreter. PureSVG - Hylograph.
Expr. Interpreter. SVG - Hylograph.
Expr. Path - Hylograph.
Expr. Path. Generators - Hylograph.
Expr. Sugar - Hylograph.
Expr. Units - Hylograph.
HATS - Hylograph.
HATS. Friendly - Hylograph.
HATS. InterpreterTick - Hylograph.
HATS. Transitions - Hylograph.
Interaction. Brush - Hylograph.
Interaction. Coordinated - Hylograph.
Interaction. Pointer - Hylograph.
Interaction. Zoom - Hylograph.
Internal. Attribute - Hylograph.
Internal. Behavior. FFI - Hylograph.
Internal. Behavior. Types - Hylograph.
Internal. Capabilities. Selection - Hylograph.
Internal. Capabilities. Transition - Hylograph.
Internal. FFI - Hylograph.
Internal. Selection. Join - Hylograph.
Internal. Selection. Operations - Hylograph.
Internal. Selection. Operations. Conversions - Hylograph.
Internal. Selection. Operations. Helpers - Hylograph.
Internal. Selection. Operations. Selection - Hylograph.
Internal. Selection. Query - Hylograph.
Internal. Selection. Types - Hylograph.
Internal. Transition. FFI - Hylograph.
Internal. Transition. Manager - Hylograph.
Internal. Transition. Scene - Hylograph.
Internal. Transition. Types - Hylograph.
Internal. Types - Hylograph.
Interpreter. D3 - Hylograph.
Interpreter. English - Hylograph.
Interpreter. Mermaid - Hylograph.
Interpreter. MetaAST - Hylograph.
Interpreter. SemiQuine - Hylograph.
Interpreter. SemiQuine. TreeToCode - Hylograph.
Interpreter. SemiQuine. Types - Hylograph.
Render - Hylograph.
Scale - Hylograph.
Scale. FP - Hylograph.
Shape. Arc - Hylograph.
Shape. Pie - Hylograph.
Shape. Polygon - Hylograph.
Tooltip - Hylograph.
Transform - Hylograph.
TreeDSL - Hylograph.
TreeDSL. ShapeTree - Hylograph.
Unified - Hylograph.
Unified. Attribute - Hylograph.
Unified. DataDSL - Hylograph.
Unified. Display - Hylograph.
Unified. Examples - Hylograph.
Unified. Join - Hylograph.
Unified. Sugar
Numeric literal