imp: csv: Allow for generating tidy csv with --layout=tidy.
This puts every date in a separate row, which is more suitable for many graphing programs.
This commit is contained in:
		
							parent
							
								
									3884f90cc6
								
							
						
					
					
						commit
						7ccf7430d0
					
				| @ -112,6 +112,7 @@ instance Default AccountListMode where def = ALFlat | ||||
| data Layout = LayoutWide (Maybe Int) | ||||
|             | LayoutTall | ||||
|             | LayoutBare | ||||
|             | LayoutTidy | ||||
|   deriving (Eq, Show) | ||||
| 
 | ||||
| -- | Standard options for customising report filtering and output. | ||||
| @ -348,6 +349,7 @@ layoutopt rawopts = fromMaybe (LayoutWide Nothing) $ layout <|> column | ||||
|         checkNames = [ ("wide", LayoutWide w) | ||||
|                      , ("tall", LayoutTall) | ||||
|                      , ("bare", LayoutBare) | ||||
|                      , ("tidy", LayoutTidy) | ||||
|                      ] | ||||
|         -- For `--layout=elided,n`, elide to the given width | ||||
|         (s,n) = break (==',') $ map toLower opt | ||||
| @ -356,7 +358,7 @@ layoutopt rawopts = fromMaybe (LayoutWide Nothing) $ layout <|> column | ||||
|               c | Just w <- readMay c -> Just w | ||||
|               _ -> usageError "width in --layout=wide,WIDTH must be an integer" | ||||
| 
 | ||||
|         err = usageError "--layout's argument should be \"wide[,WIDTH]\", \"tall\", or \"bare\"" | ||||
|         err = usageError "--layout's argument should be \"wide[,WIDTH]\", \"tall\", \"bare\", or \"tidy\"" | ||||
| 
 | ||||
| -- Get the period specified by any -b/--begin, -e/--end and/or -p/--period | ||||
| -- options appearing in the command line. | ||||
|  | ||||
| @ -525,13 +525,17 @@ multiBalanceReportAsCsv opts@ReportOpts{..} = | ||||
| 
 | ||||
| multiBalanceReportAsCsv' :: ReportOpts -> MultiBalanceReport -> (CSV, CSV) | ||||
| multiBalanceReportAsCsv' opts@ReportOpts{..} (PeriodicReport colspans items tr) = | ||||
|     ( ("account" : ["commodity" | layout_ == LayoutBare] ++ map showDateSpan colspans | ||||
|        ++ ["total"   | row_total_] | ||||
|        ++ ["average" | average_] | ||||
|       ) : concatMap (fullRowAsTexts (accountNameDrop drop_ . prrFullName)) items | ||||
|     , totalrows) | ||||
|     ( headers : concatMap (fullRowAsTexts (accountNameDrop drop_ . prrFullName)) items | ||||
|     , totalrows | ||||
|     ) | ||||
|   where | ||||
|     fullRowAsTexts render row = (render row :) <$> multiBalanceRowAsCsvText opts row | ||||
|     headers = "account" : case layout_ of | ||||
|       LayoutTidy -> ["date", "commodity", "value"] | ||||
|       LayoutBare -> "commodity" : dateHeaders | ||||
|       _          -> dateHeaders | ||||
|     dateHeaders = map showDateSpan colspans ++ ["total" | row_total_] ++ ["average" | average_] | ||||
| 
 | ||||
|     fullRowAsTexts render row = map (render row :) $ multiBalanceRowAsCsvText opts colspans row | ||||
|     totalrows | ||||
|       | no_total_ = mempty | ||||
|       | otherwise = fullRowAsTexts (const "total") tr | ||||
| @ -692,8 +696,8 @@ balanceReportAsTable opts@ReportOpts{average_, row_total_, balanceaccum_} | ||||
|     maybetranspose | transpose_ opts = \(Table rh ch vals) -> Table ch rh (transpose vals) | ||||
|                    | otherwise       = id | ||||
| 
 | ||||
| multiBalanceRowAsWbs :: AmountDisplayOpts -> ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder]] | ||||
| multiBalanceRowAsWbs bopts ReportOpts{..} (PeriodicReportRow _ as rowtot rowavg) = | ||||
| multiBalanceRowAsWbs :: AmountDisplayOpts -> ReportOpts -> [DateSpan] -> PeriodicReportRow a MixedAmount -> [[WideBuilder]] | ||||
| multiBalanceRowAsWbs bopts ReportOpts{..} colspans (PeriodicReportRow _ as rowtot rowavg) = | ||||
|     case layout_ of | ||||
|       LayoutWide width -> [fmap (showMixedAmountB bopts{displayMaxWidth=width}) all] | ||||
|       LayoutTall       -> paddedTranspose mempty | ||||
| @ -703,12 +707,20 @@ multiBalanceRowAsWbs bopts ReportOpts{..} (PeriodicReportRow _ as rowtot rowavg) | ||||
|                            . transpose                         -- each row becomes a list of Text quantities | ||||
|                            . fmap (showMixedAmountLinesB bopts{displayOrder=Just cs, displayMinWidth=Nothing}) | ||||
|                            $ all | ||||
|       LayoutTidy       -> concat | ||||
|                            . zipWith (\d -> map (wbFromText d :)) dates | ||||
|                            . fmap ( zipWith (\c a -> [wbFromText c, a]) cs | ||||
|                                   . showMixedAmountLinesB bopts{displayOrder=Just cs, displayMinWidth=Nothing}) | ||||
|                            $ all | ||||
|   where | ||||
|     totalscolumn = row_total_ && balanceaccum_ `notElem` [Cumulative, Historical] | ||||
|     cs = S.toList . foldl' S.union mempty $ fmap maCommodities all | ||||
|     all = as | ||||
|         ++ [rowtot | totalscolumn && not (null as)] | ||||
|         ++ [rowavg | average_     && not (null as)] | ||||
|     dates = map showDateSpan colspans | ||||
|         ++ ["Total"   | totalscolumn && not (null as)] | ||||
|         ++ ["Average" | average_     && not (null as)] | ||||
| 
 | ||||
|     paddedTranspose :: a -> [[a]] -> [[a]] | ||||
|     paddedTranspose _ [] = [[]] | ||||
| @ -724,11 +736,11 @@ multiBalanceRowAsWbs bopts ReportOpts{..} (PeriodicReportRow _ as rowtot rowavg) | ||||
|           m (x:xs) = x:xs | ||||
|           m [] = [n] | ||||
| 
 | ||||
| multiBalanceRowAsCsvText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[T.Text]] | ||||
| multiBalanceRowAsCsvText opts = fmap (fmap wbToText) . multiBalanceRowAsWbs (balanceOpts False opts) opts | ||||
| multiBalanceRowAsCsvText :: ReportOpts -> [DateSpan] -> PeriodicReportRow a MixedAmount -> [[T.Text]] | ||||
| multiBalanceRowAsCsvText opts colspans = fmap (fmap wbToText) . multiBalanceRowAsWbs (balanceOpts False opts) opts colspans | ||||
| 
 | ||||
| multiBalanceRowAsTableText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder]] | ||||
| multiBalanceRowAsTableText opts = multiBalanceRowAsWbs (balanceOpts True opts) opts | ||||
| multiBalanceRowAsTableText opts = multiBalanceRowAsWbs (balanceOpts True opts) opts [] | ||||
| 
 | ||||
| -- | Amount display options to use for balance reports | ||||
| balanceOpts :: Bool -> ReportOpts -> AmountDisplayOpts | ||||
|  | ||||
| @ -272,7 +272,7 @@ compoundBalanceReportAsCsv ropts (CompoundPeriodicReport title colspans subrepor | ||||
|             map (length . prDates . second3) subreports | ||||
|     addtotals | ||||
|       | no_total_ ropts || length subreports == 1 = id | ||||
|       | otherwise = (++ fmap ("Net:" : ) (multiBalanceRowAsCsvText ropts netrow)) | ||||
|       | otherwise = (++ fmap ("Net:" : ) (multiBalanceRowAsCsvText ropts colspans netrow)) | ||||
| 
 | ||||
| -- | Render a compound balance report as HTML. | ||||
| compoundBalanceReportAsHtml :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> Html () | ||||
| @ -309,7 +309,7 @@ compoundBalanceReportAsHtml ropts cbr = | ||||
|         ++ [blankrow] | ||||
| 
 | ||||
|     totalrows | no_total_ ropts || length subreports == 1 = [] | ||||
|       | otherwise = multiBalanceReportHtmlFootRow ropts <$> (("Net:" :) <$> multiBalanceRowAsCsvText ropts netrow) | ||||
|       | otherwise = multiBalanceReportHtmlFootRow ropts <$> (("Net:" :) <$> multiBalanceRowAsCsvText ropts colspans netrow) | ||||
|   in do | ||||
|     style_ (T.unlines ["" | ||||
|       ,"td { padding:0 0.5em; }" | ||||
|  | ||||
| @ -235,3 +235,49 @@ Balance Sheet 2014-10-11 | ||||
|                       || VEA                   36.00  | ||||
|                       || VHT                  294.00  | ||||
| >=0 | ||||
| 
 | ||||
| # 13. Multicolumn balance report csv output with --layout=tidy | ||||
| $ hledger -f bcexample.hledger bal -T -Y assets.*etrade -3 -O csv --layout=tidy | ||||
| > | ||||
| "account","date","commodity","value" | ||||
| "Assets:US:ETrade","2012","GLD","0" | ||||
| "Assets:US:ETrade","2012","ITOT","10.00" | ||||
| "Assets:US:ETrade","2012","USD","337.18" | ||||
| "Assets:US:ETrade","2012","VEA","12.00" | ||||
| "Assets:US:ETrade","2012","VHT","106.00" | ||||
| "Assets:US:ETrade","2013","GLD","70.00" | ||||
| "Assets:US:ETrade","2013","ITOT","18.00" | ||||
| "Assets:US:ETrade","2013","USD","-98.12" | ||||
| "Assets:US:ETrade","2013","VEA","10.00" | ||||
| "Assets:US:ETrade","2013","VHT","18.00" | ||||
| "Assets:US:ETrade","2014","GLD","0" | ||||
| "Assets:US:ETrade","2014","ITOT","-11.00" | ||||
| "Assets:US:ETrade","2014","USD","4881.44" | ||||
| "Assets:US:ETrade","2014","VEA","14.00" | ||||
| "Assets:US:ETrade","2014","VHT","170.00" | ||||
| "Assets:US:ETrade","Total","GLD","70.00" | ||||
| "Assets:US:ETrade","Total","ITOT","17.00" | ||||
| "Assets:US:ETrade","Total","USD","5120.50" | ||||
| "Assets:US:ETrade","Total","VEA","36.00" | ||||
| "Assets:US:ETrade","Total","VHT","294.00" | ||||
| "total","2012","GLD","0" | ||||
| "total","2012","ITOT","10.00" | ||||
| "total","2012","USD","337.18" | ||||
| "total","2012","VEA","12.00" | ||||
| "total","2012","VHT","106.00" | ||||
| "total","2013","GLD","70.00" | ||||
| "total","2013","ITOT","18.00" | ||||
| "total","2013","USD","-98.12" | ||||
| "total","2013","VEA","10.00" | ||||
| "total","2013","VHT","18.00" | ||||
| "total","2014","GLD","0" | ||||
| "total","2014","ITOT","-11.00" | ||||
| "total","2014","USD","4881.44" | ||||
| "total","2014","VEA","14.00" | ||||
| "total","2014","VHT","170.00" | ||||
| "total","Total","GLD","70.00" | ||||
| "total","Total","ITOT","17.00" | ||||
| "total","Total","USD","5120.50" | ||||
| "total","Total","VEA","36.00" | ||||
| "total","Total","VHT","294.00" | ||||
| >=0 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user