vega-view 0.3.1.2 → 0.3.1.3
raw patch · 3 files changed
+87/−57 lines, 3 files
Files
- ChangeLog.md +10/−0
- app/Main.hs +76/−56
- vega-view.cabal +1/−1
ChangeLog.md view
@@ -1,5 +1,15 @@ # Changelog for vega-view +## 0.3.1.3++Change the appearance and linking of directory names, in the "label"+of a plot (drop the path and show just the file name), and on the web+pages. A common stanza is used to indicate the current directory or file+and the path to the "parent".++There have been style changes to how the inline plots are displayed,+to allow them to be horizontally scrolled.+ ## 0.3.1.2 The "view a visualization" page - i.e. /display/..path-to-spec - now
app/Main.hs view
@@ -50,7 +50,7 @@ import Network.HTTP.Types (status404) import System.Directory (doesDirectoryExist, listDirectory) import System.Environment (lookupEnv)-import System.FilePath ((</>), takeDirectory, takeFileName)+import System.FilePath ((</>), splitFileName, takeFileName) import Text.Blaze.Html5 ((!)) import Text.Blaze.Html.Renderer.Text (renderHtml) import Web.Scotty (ScottyM, ActionM@@ -82,6 +82,9 @@ data Spec = Spec { specVis :: Object , specPath :: FilePath+ -- ^ the path to the file+ , specFileName :: String+ -- ^ the file name with no path } @@ -110,7 +113,7 @@ , H.toHtml specId , "'); " , "const vopts = { downloadFileName: '"- , H.toHtml (specPath spec)+ , H.toHtml (specFileName spec) , "' }; " , "vegaEmbed(vdiv, " , H.toHtml (LB8.unpack (encode vis))@@ -125,7 +128,7 @@ in (H.div ! A.class_ "vizview") $ do -- unlike embedSpec JS routines, do not add close or hide buttons- (H.p ! A.class_ "location") (H.toHtml ("File: " ++ specPath spec))+ (H.p ! A.class_ "location") (H.toHtml ("File: " ++ specFileName spec)) (H.div ! A.class_ "contents") $ do case mDesc of@@ -161,7 +164,9 @@ readSpec infile = do cts <- either (Left . show) Right <$> readJSON infile pure $ case cts of- Right (Object o) -> Right (Spec o infile)+ Right (Object o) ->+ let (path, filename) = splitFileName infile+ in Right (Spec o path filename) Right _ -> Left "JSON was not an object" Left e -> Left e @@ -186,12 +191,10 @@ , "} " ] --- TODO: should parent node be emoved from DOM on close? depends on--- what page it is being used in+ addTitleJS = [ "function addTitle(div, contents, infile) { " , "const el = document.createElement('p'); " , "el.setAttribute('class', 'location'); "- , "addText(el, 'File: ' + infile); " , "div.appendChild(el); " , "const close = document.createElement('span'); " , "close.setAttribute('class', 'close'); "@@ -202,7 +205,7 @@ , "div.removeChild(div.firstChild); " , "} " , "}); "- , "const hide = document.createElement('hide'); "+ , "const hide = document.createElement('span'); " , "hide.setAttribute('class', 'hide'); " , "el.appendChild(hide); " , "hide.addEventListener('click', (ev) => { "@@ -212,6 +215,7 @@ , "contents.style.display = 'block'; " , "hide.setAttribute('class', 'hide'); } " , "}); "+ , "addText(el, 'File: ' + infile); " , "} " ] @@ -315,7 +319,8 @@ , "background: rgba(230, 20, 20, 0.6); " , "border-radius: 50%; " , "cursor: pointer; "- , "float: left; "+ , "display: inline-block; "+ -- , "float: left; " , "height: 1em; " , "margin-right: 0.5em; " , "width: 1em; "@@ -330,7 +335,8 @@ , "border-right: 0.5em solid transparent; " , "border-top: 1em solid rgba(255, 165, 0, 0.6); " , "cursor: pointer; "- , "float: left; "+ , "display: inline-block; "+ -- , "float: left; " , "height: 0; " , "margin-right: 0.5em; " , "width: 0; "@@ -340,7 +346,8 @@ , "border-right: 0.5em solid transparent; " , "border-bottom: 1em solid rgba(255, 165, 0, 0.6); " , "cursor: pointer; "- , "float: left; "+ , "display: inline-block; "+ -- , "float: left; " , "height: 0; " , "margin-right: 0.5em; " , "width: 0; "@@ -366,6 +373,9 @@ , "margin: -1em; " , "margin-bottom: 0; " , "padding: 0.5em; "+ -- add a little horizontal space before the end of the "window"+ -- for when the visualization is minimised+ , "padding-right: 1.5em; " , "} " , "div.contents { " , "margin: 0; "@@ -551,12 +561,7 @@ makeLi :: FilePath -> H.Html makeLi infile = H.li (pageLink infile) -makeParentLink :: FilePath -> H.Html-makeParentLink indir =- let toHref = H.toValue ("/display" </> indir </> "..")- in (H.a ! A.href toHref) "parent directory" - embedLink :: FilePath -> H.Html embedLink infile = let toHref = H.toValue ("/embed" </> infile)@@ -583,8 +588,7 @@ if indir == "." then H.p "There is nothing to see in the base directory!" else do- H.p (H.toHtml ("Directory: " ++ indir))- H.p (makeParentLink indir)+ labelDirectory True indir H.p "There is nothing to see here!" in html (renderHtml page)@@ -624,7 +628,9 @@ , "addDescription(contents, tgt.response.spec); " , "const vdiv = document.createElement('div'); " , "contents.appendChild(vdiv); "- , "vegaEmbed(vdiv, tgt.response.spec, vopts).catch((err) => { "+ , "vegaEmbed(vdiv, tgt.response.spec, vopts).then((result) => { "+ , "resetLocationWidth(div); "+ , "}).catch((err) => { " , "vdiv.appendChild(document.createTextNode(err)); " , "vdiv.setAttribute('class', 'vega-error'); " , "}); "@@ -633,7 +639,8 @@ , "} " , "div.style.display = 'block';" , "} "- ] ++ addTextJS ++ addTitleJS ++ addDescriptionJS+ ] ++ addTextJS ++ addTitleJS ++ addDescriptionJS +++ resetLocationJS in (H.script ! A.type_ "text/javascript") (mconcat cts) @@ -642,17 +649,41 @@ embedCSS = let cts = [ ".vizview { " , "display: none; "- , "left: 2em; "- -- , "overflow: hidden; " why did I add this?- , "position: fixed; "- , "top: 2em; "+ -- , "float: left; "+ , "overflow: auto; " -- is this worth it? , "} "+ , ".vizlist { "+ , "display: flex; "+ , "justify-content: space-around; "+ , "}"+ , "#visualizations { "+ -- , "clear: both; " -- only needed if vizview is float+ , "} " ] ++ closeCSS ++ hideCSS ++ descriptionCSS ++ locationCSS ++ pageSetupCSS ++ vegaErrorCSS ++ vizCSS in toCSS cts +labelDirectory ::+ Bool+ -- ^ If True then the parent directory is ../ above the input directory+ -- and the link label includes the term "parent".+ -> FilePath+ -- ^ The directory name for display to the user+ -> H.Html+labelDirectory goUp dirName = do+ H.p (H.toHtml ("Directory: " ++ dirName))+ let baseURL = "/display" </> dirName+ url = if goUp then baseURL </> ".." else baseURL+ label = mconcat [ if goUp then "parent " else "", "directory" ]++ H.p (mconcat [ "Go to "+ , (H.a ! A.href (H.toValue url)) label+ , "."+ ])++ showDir :: FilePath -> ([FilePath], [(FilePath, H.Html)])@@ -675,8 +706,7 @@ (H.div ! A.id "mainbar") $ do unless atTop $ do- H.p (H.toHtml ("Directory: " ++ indir))- H.p (makeParentLink indir)+ labelDirectory True indir unless (null subdirs) $ do H.h2 "Sub-directories"@@ -688,8 +718,10 @@ -- previous visualization when viewing one. -- unless (null files) $ do- (H.div ! A.class_ "vizview" ! A.id "vizview") ""- (H.div ! A.id "vizlist") $ do+ (H.div ! A.class_ "vizlist") $+ (H.div ! A.class_ "vizview" ! A.id "vizview") ""++ (H.div ! A.id "visualizations") $ do H.h2 "Visualizations" H.table $ do H.thead $@@ -726,18 +758,6 @@ load "vega-embed@4" "" -{--try -align-items or align-self from-https://stackoverflow.com/questions/40141163/make-flex-items-take-content-width-not-width-of-parent-container--want to get title of block the full container width, and also get things working for inline/drag+drop--how about adding a resize handler on the window to adjust all the-vizview.location widths, and then trigger this on creation too---}- pageCSS :: H.Html pageCSS = let cts = pageSetupCSS ++@@ -765,18 +785,20 @@ -- visualization. -- pageJS :: H.Html-pageJS =- let cts = [ "function resetLocationWidth(div) { "- , "const locs = div.getElementsByClassName('location'); "- , "if (locs.length === 0) { console.log('DBG: no location'); console.log({div}); return; } "- , "const loc = locs[0]; "- , "loc.style.width = div.scrollWidth + 'px'; "- , "} "- ]+pageJS = toJS resetLocationJS - in toJS cts +resetLocationJS :: [H.Html]+resetLocationJS =+ [ "function resetLocationWidth(div) { "+ , "const locs = div.getElementsByClassName('location'); "+ , "if (locs.length === 0) { console.log('DBG: no location'); console.log({div}); return; } "+ , "const loc = locs[0]; "+ , "loc.style.width = div.scrollWidth + 'px'; "+ , "} "+ ] + showPage :: FilePath -> ActionM () showPage infile = do espec <- liftIO (readSpec infile)@@ -805,12 +827,9 @@ homeLink (H.div ! A.id "mainbar") $ do- H.p $ H.toHtml (mconcat ["Go to ", parentLink])+ labelDirectory False (specPath spec) (H.div ! A.class_ "vizlist") contents - dirName = H.toValue ("/display" </> takeDirectory infile)- parentLink = (H.a ! A.href dirName) "parent directory"- in html (renderHtml page) @@ -828,9 +847,10 @@ embedPage infile = do espec <- liftIO (readSpec infile) case espec of- Right (Spec o _) -> json (object [ "spec" .= Object o- , "infile" .= infile- ])+ Right (Spec o path filename) -> json (object [ "spec" .= Object o+ , "path" .= path+ , "infile" .= filename+ ]) _ -> errorStatus
vega-view.cabal view
@@ -1,5 +1,5 @@ name: vega-view-version: 0.3.1.2+version: 0.3.1.3 synopsis: Easily view Vega or Vega-Lite visualizations. description: A web server that is used to view all the Vega and Vega-Lite specifications in a directory, or sub-directory. It is similar