@@ -0,0 +1,95 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+module ProjectM36.Relation.Show.Gnuplot where
3+import ProjectM36.Base
4+import ProjectM36.Relation
5+import ProjectM36.Tuple
6+import qualified ProjectM36.Attribute as A
7+import Graphics.EasyPlot
8+import qualified Data.Vector as V
9+
10+--this module support plotting relations containing integer attributes with arity 1,2, or 3 only
11+--nested relations?
12+
13+data PlotError = InvalidAttributeCountError |
14+ InvalidAttributeTypeError
15+ deriving (Show)
16+
17+--plotRelation :: Relation -> Either PlotError
18+
19+intFromAtomIndex :: Int -> RelationTuple -> Int
20+intFromAtomIndex index tup = (\(IntAtom i) -> i) $ (tupleAtoms tup) V.! index
21+
22+graph1DRelation :: Relation -> Graph2D Double Double
23+graph1DRelation rel = Data2D [Title "rel"] [] $ map (\i -> (fromIntegral i, 0.0)) (points1DRelation rel)
24+
25+points1DRelation :: Relation -> [Int]
26+points1DRelation rel = relFold folder [] rel
27+ where
28+ folder tup acc = intFromAtomIndex 0 tup : acc
29+
30+graph2DRelation :: Relation -> Graph2D Double Double
31+graph2DRelation rel = Data2D [Title "rel"] [Step 1.0] $ map (\(x,y) -> (fromIntegral x, fromIntegral y)) $ points2DRelation rel
32+
33+points2DRelation :: Relation -> [(Int, Int)]
34+points2DRelation rel = relFold folder [] rel
35+ where
36+ folder tup acc = (intFromAtomIndex 0 tup, intFromAtomIndex 1 tup) : acc
37+
38+graph3DRelation :: Relation -> Graph3D Double Double Double
39+graph3DRelation rel = Data3D [Title "rel"] [StepX 1.0, StepY 1.0] $ map (\(x,y,z) -> (fromIntegral x, fromIntegral y, fromIntegral z)) $ points3DRelation rel
40+
41+points3DRelation :: Relation -> [(Int, Int, Int)]
42+points3DRelation rel = relFold folder [] rel
43+ where
44+ folder tup acc = (intFromAtomIndex 0 tup, intFromAtomIndex 1 tup, intFromAtomIndex 2 tup) : acc
45+
46+sample1DRelation = case mkRelationFromList (A.attributesFromList [Attribute "x" IntAtomType]) [[IntAtom 2], [IntAtom 3]] of
47+ Right rel -> rel
48+ Left _ -> undefined
49+
50+sample2dRelation = case mkRelationFromList (A.attributesFromList [Attribute "x" IntAtomType, Attribute "y" IntAtomType]) [[IntAtom 2, IntAtom 3],
51+ [IntAtom 2, IntAtom 4]] of
52+ Right rel -> rel
53+ Left _ -> undefined
54+
55+sample3dRelation = case mkRelationFromList (A.attributesFromList [Attribute "x" IntAtomType, Attribute "y" IntAtomType, Attribute "z" IntAtomType]) [[IntAtom 2, IntAtom 3, IntAtom 3],
56+ [IntAtom 2, IntAtom 4, IntAtom 4]] of
57+ Right rel -> rel
58+ Left _ -> undefined
59+
60+type G2D = Graph2D Double Double
61+type G3D = Graph3D Double Double Double
62+
63+plotRelation :: Relation -> Either PlotError (Either G2D G3D)
64+plotRelation rel = let attrTypes = V.replicate (arity rel) IntAtomType in
65+ if attrTypes /= A.atomTypes (attributes rel) then
66+ Left InvalidAttributeTypeError
67+ else
68+ case arity rel of
69+ 1 -> Right $ Left $ graph1DRelation rel
70+ 2 -> Right $ Left $ graph2DRelation rel
71+ 3 -> Right $ Right $ graph3DRelation rel
72+ _ -> Left InvalidAttributeCountError
73+
74+--PNG
75+savePlottedRelation :: String -> Relation -> IO ()
76+savePlottedRelation path rel = case plotRelation rel of
77+ Left err -> putStrLn (show err)
78+ Right (Left g2d) -> plot' [] (PNG path) g2d >> return ()
79+ Right (Right g3d) -> plot' [] (PNG path) g3d >> return ()
80+
81+--X11
82+showPlottedRelation :: Relation -> IO ()
83+showPlottedRelation rel = case plotRelation rel of
84+ Left err -> putStrLn (show err)
85+ Right (Left g2d) -> plot' [] X11 g2d >> return ()
86+ Right (Right g3d) -> plot' [] X11 g3d >> return ()
87+
88+
89+ezplot :: Relation -> IO ()
90+ezplot rel = do
91+ case plotRelation rel of
92+ Left err -> putStrLn $ show err
93+ Right (Left g2d) -> plot' [Interactive] X11 g2d >> return ()
94+ Right (Right g3d) -> plot' [Interactive] X11 g3d >> return ()
95+