" Vimball Archiver by Charles E. Campbell, Jr., Ph.D. UseVimball finish autoload/treemap.vim [[[1 71 " vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " Menu {{{1 " Run :menu Plugin.&Treemap.&Runmain() :call treemap#main(g:tmOutput,g:tmSeparator) " Create & Print :menu Plugin.&Treemap.&Createcreate() :call treemap#create(g:tmSeparator) :menu Plugin.&Treemap.&Drawdraw() :call treemap#draw(g:tmOutput) " Print log variable g:tmMess :menu Plugin.&Treemap.&Logg:tmMess :call treemap#printAllMessages(g:tmMess,$lang) " Title :menu Plugin.&Treemap.&Titleg:tmTitle :let g:tmTitle = inputdialog("Title:","Treemap","Treemap") " Color :menu Plugin.&Treemap.&Color.BLUE/GREY/RED :let g:tmColor = ['blue','grey','red'] :menu Plugin.&Treemap.&Color.BLUE/YELLOW/RED :let g:tmColor = ['blue','yellow','red'] :menu Plugin.&Treemap.&Color.GREEN/BLUE/YELLOW :let g:tmColor = ['green','blue','yellow'] :menu Plugin.&Treemap.&Color.GREEN/YELLOW/BLUE :let g:tmColor = ['green','yellow','blue'] :menu Plugin.&Treemap.&Color.GREEN/YELLOW/RED :let g:tmColor = ['green','yellow','red'] :menu Plugin.&Treemap.&Color.YELLOW/GREEN/RED :let g:tmColor = ['yellow','green','red'] :menu Plugin.&Treemap.&Color.YELLOW/GREY/BLUE :let g:tmColor = ['yellow','grey','blue'] " Output :menu Plugin.&Treemap.&Output\ Type.VIM\ :let g:tmOutput = 'VIM' :menu Plugin.&Treemap.&Output\ Type.SVG\ :let g:tmOutput = 'SVG' " Separator :menu Plugin.&Treemap.&Separator.Semicolon; :let g:tmSeparator = ';' :menu Plugin.&Treemap.&Separator.Tabulator\\t :let g:tmSeparator = '\t' :menu Plugin.&Treemap.&Separator.Comma, :let g:tmSeparator = ',' :menu Plugin.&Treemap.&Separator.Vertical\ Bar\| :let g:tmSeparator = '\|' :menu Plugin.&Treemap.&Separator.Slash/ :let g:tmSeparator = '/' :menu Plugin.&Treemap.&Separator.Backslash\\ :let g:tmSeparator = '\' " Size :menu Plugin.&Treemap.&Size.Widthg:tmUx :let g:tmUx = inputdialog("Width:",1024,1024) :menu Plugin.&Treemap.&Size.Heightg:tmUy :let g:tmUy = inputdialog("Height:",768,768) " Commands {{{1 :command! -count=1 TmRun \ call treemap#main(g:tmOutput,g:tmSeparator) :command! -count=1 TmCreate \ call treemap#create(g:tmSeparator) :command! -count=1 TmDraw \ call treemap#draw(g:tmOutput) :command! -count=1 TmLog \ call treemap#printAllMessages(g:tmMess,$lang) :command! -count=1 TmTitle \ let g:tmTitle = input("Title: ","Treemap") :command! -count=1 TmColor \ let g:tmColor = [] | \ call add(g:tmColor,input("Choose first Color: ","blue")) | \ call add(g:tmColor,input("Choose second Color: ","grey")) | \ call add(g:tmColor,input("Choose first Color: ","red")) :command! -count=1 TmSeparator \ let g:tmSeparator = input("Separator: ","\t") :command! -count=1 TmOutput \ let g:tmOutput = input("Output Type: ","VIM") :command! -count=1 TmWidth \ let g:tmUx= input("Width: ","70") :command! -count=1 TmHeight \ let g:tmUy= input("Hight: ","25") " Mappings {{{1 :map tr :TmRun :map tc :TmCreate :map td :TmDraw :map tl :TmLog doc/treemap.txt [[[1 948 " vim: filetype=help foldmethod=marker foldmarker=<<<,>>> nomodifiable readonly *treemap.txt* For Vim version 7.4. Last change: 2015 Apr 30 VIM REFERENCE MANUAL by Data Statiker Treemap extension plugin (treemap.vim) manual treemap.vim version 0.9.2 For instructions on installing this file, type :help add-local-help |add-local-help| inside Vim. Homepage: https://github.com/Data-Statiker/VIM-TREEMAP *treemap* *treemap.vim* *tree_map* *tree_map.vim* 1. Getting Started |treemap-getting-started| 2. Whats New |treemap-new| 3. Overview |treemap-overview| 4. Installation |treemap-install| 5. Configuration |treemap-configure| 5.1 Output Type |treemap-configure-output| 5.2 Separator |treemap-configure-separator| 5.3 Colors |treemap-configure-color| 5.4 Size |treemap-configure-size| 5.5 Title |treemap-configure-title| 5.6 Logs |treemap-configure-logs| 5.7 Clipboard |treemap-configure-clipboard| 5.8 Other |treemap-configure-other| 6. Menu |treemap-menu| 7. Example |treemap-example| 8. Colorization |treemap-colorization| 9. Message Handling |treemap-message| 10. Commands |treemap-commands| 11. Mappings |treemap-mappings| {Vi does not have any of this} ============================================================================== 1. Getting Started *treemap-getting-started* With the treemap extension plugin for vim you can create treemaps with the output in a textfile or an imbedded SVG HTML file. First install the plugin: |treemap-install| To start the treemap creation: - load the inputfile - set the separator (;|,|\t|...) in the menu Plugin->Treemap->Separator or with the VIM Command :TmSeparator (tr) - set the output type 'VIM' or 'SVG' in the menu Plugin->Treemap->Output Type or with the VIM Command :TmOutput - Run the treemap script in the menu Plugin->Treemap->Run or with the VIM Command :TmRun OR call the main function: call treemap#main(output,separator) for example: - call treemap#main('VIM','\t') - call treemap#main(g:tmOutput,g:tmSeparator) +-----------------------------------------------------------+ | Note: | | Set tho option wrap to 'nowrap' | | :set nowrap! | | Otherwise the treemap is displayed wrong. You can set this| | option also after drawing the treemap! | +-----------------------------------------------------------+ +--------------------------------------------------------------+ | Note: | | The decimal separator for the input file is in every language| | the point "." | | examples: 23.1 | | 1020.23 | +--------------------------------------------------------------+ Use commands |TmCreate| and |TmDraw| instead of |TmRun|. ============================================================================== 2. Whats New *treemap-new* Version 0.9.2: * New Commands TmCreate and TmDraw To seperate the calculating and drawing of treemap * Create folders in plugin files for a clear view Version 0.9.1: * Add corresponding VIM COMMANDS for each menu entry: |treemap-commands| * Add Mappings for VIM Commands: |treemap-mappings| * Set the default width and height in case of Output Type 'VIM' to 70*25 Version 0.9: * Title for the treemap * Initialize g:tmMess / no error occurs by starting "print log" * Namespace for treemap global variables: g:tm* To avoid incompatibility to other plugins * Small changes in the help file Version 0.8: * Introduce the global variables g:tmUx and g:tmUy to set the size from the treemap. So the size of the treemap could be changed throug the variables: g:tmUx = width g:tmUy = height * Adapt the menu to set the height and width of the treemap * Adapt the menu for printing the log variable g:tmMess * Update VIM help file treemap.txt * For some parameters in the function treemap#initialize() Only set the variables when they do not exist * New function treemap#checkChildParentRelation(matrix,val2Active) Check if every unit has only one parent Version 0.7: * In version 0.7 the output paramater is created for the function treemap#main(). The paramater output could have the values "VIM" or "SVG". VIM: Rectangles are created in a new tab with the signs "-", "|" and "+" SVG: Rectangles are descripted in a SVG structure imbedded in a html file * New function treemap#initialize for initializing global variables * New parameter separator for the method treemap#main(). So the input file could be separated by ";" or "\t" (tab) or any other signs. The values of these parameter are for example: ; for semicolon separated files \t for tabulator separated files Examples: :call treemap#main('VIM',';') :call treemap#main('SVG','\t') * Insert 'throw "oops"' in treemap#interruptRun() so the program stops in case of error * Create the menu "Plugin - Treemap" tor run the script and set the variables g:tmSeparator, g:tmOutput, g:tmColor Version 0.6: * Delete not used functions "treemap#reorgHierachy" and "treemap#reorgHierachy2" with all sub functions * Rename function "treemap#reorgHierachy3" to "treemap#reorgHierachy" * Add a second value column. This value is represented in the treemap through colors (Heat Map). Only SVG-Output. If ther is no val 2 column, the layer 1 entries define the color of their childs Version 0.5: * In version 0.5 the recursive function "treemap#reorgHierachy2" is substitute through the iterative function "treemap#reorgHierachy3" * SVG-Output with fill color ============================================================================== 3. Overview *treemap-overview* With the treemap extension plugin for vim you can create treemaps with the output in a textfile or an imbedded SVG HTML file. To create a treemap you need an input file. This file has to be character seperated (CSV) and needs a headline. Example for an input file: folder;file;size treemap;treemap.vim;12 treemap;readme.txt;6 xml;xmlcleaner.vim;16 xml;readme.md;7 To create a treemap do the following: 1 Open this input file in VIM vim inputfile.txt 2 Select the correct separator Menu: Plugin->Treemap->Separator Command: TmSeparator In the example case use the separator "Semicolon ;" 3 Select your favourite output type Menu: Plugin->Treemap->Output Type Command: TmOutput see |treemap-configure-output| and |treemap-menu| or |TmOutput| The standard Output is "VIM " 4a Start the treemap generation Menu: Plugin->Treemap->Run main() Command: TmRun Mapping: tr (in most cases = "\") This call needs a headline! Then a new tab opens. In case of the output type SVG you get the SVG/HTML Code in the new tab and in the other case (VIM) the treemap is drawn in the new tab with the signs "|","+" and "-". 4b Instead of using 4a you can also use the commands |TmCreate| and |TmDraw|. Menu: Plugin->Treemap->Create create() Plugin->Treemap->Draw draw() Commands: TmCreate TmDraw Mappings: tc td TmCreate creates the rectangles and save this to the tmClipboard. TmDraw draw the rectangles to the current position of your cursor. +--------------------------------------------------------+ |Note: | |To use TmCreate you have to select a marked area of the | |input data! Don't select a headline!! | | | |If you use the visual-mode, don't use the command | |":TmCreate". You overwrite your data with that. | |Use instead the menu entry "Create" or tc. | |(visual-block mode is no problem) | +--------------------------------------------------------+ +-------------------------------------------------------------+ |Note: | |You start the visual mode with: 'v' | |You start the visual block mode with: | | Linux | | Windows | |Then use the keys "h, j, k, l" to mark the area you want to | |select. (Keys: h - , j - , k - , l - )| +-------------------------------------------------------------+ Instead of use the menu you can set the paramters and start the generation directly: - Separator variable: g:tmSeparator // example: :let g:tmSeparator = ";" - Output Type variable: g:tmOutput // example: :let g:tmOutput = "VIM" - Run the generation function treemap#main(output,separator) // example: :call treemap#main("VIM",";") Other paramters: You can change the size of the treemap with the following variables: - g:tmUx - width // example: :let g:tmUx = 230 - g:tmUy - height // example: :let g:tmUy = 65 To do that you can use the menu "Plugin"->"Treemap"->"Size" or the Vim Commands :TmWidth and :TmHeight If this parameters aren't set, the default values are taken: VIM: 70 * 25 SVG: 1024 * 768 The title of a treemap can defined in the menu or Command: Menu: Plugin->Treemap->Title g:tmTitle (|treemap-menu|) Command: |TmTitle| After executing this menu point youn can insert the name of your Treemap in a input popup. You can also set the variable g:tmTitle directly: :let g:tmTitle = "MyTreemapName" In case of output type "VIM": The title is written in line 1 of the output tab In case of output type "SVG": - The title is used in the HTML Header as - The title is used as a headline for the SVG graphic +-------------------------------------------------------------+ |Note: | |The decimal separator for the input file is in every language| |the point "." | | examples: 23.1 | | 1020.23 | +-------------------------------------------------------------+ ============================================================================== 4. Installation *treemap-install* VIMBALL: ********* Download the vimball file treemap.vmb from: http://www.vim.org/scripts/script.php?script_id=5157 Install the vimball file with VIM 1 Download the file treemap.vmb 2 vim path/treemap.vmb 3 :so % 4 :q Now you have the menu Plugin->Treemap GITHUB: ********* GITHUB Repository: https://github.com/Data-Statiker/VIM-TREEMAP When you have the files from GITHUB: Copy the folders 'autoload', 'doc' and 'plugin' to your local vimfiles: ~/.vim/doc OR (Windows) C:\Users\YourUsername\vimfiles\doc HELP FILE: *********** To activate the helpfile in VIM type in command mode: :helptags ~/.vim/doc OR (Windows) :helptags C:\Users\YourUsername\vimfiles\doc ============================================================================== 5. Configuration *treemap-configure* 5.1 Output Type *treemap-configure-output* global variable: g:tmOutput Default value: "VIM" Defines the output type of the treemap - VIM : the treemap is drawn in a new tabulator with the signs "|", "-" and "+" - SVG : the HTML/SVG code of the treemap is printed in a new tabulator. Save this file and open it in a browser. You can choose the output type in the menu: |treemap-menu| Or set the variable directly: :let g:tmOutput = "VIM" :let g:tmOutput = "SVG" ----------------------------------------------------------------------------- 5.2 Separator *treemap-configure-separator* global variable: g:tmSeparator Default value: "\t" Defines the character of the separator the input file is separated with: The following character can be choosen in the menu: Semicolon ; Tabulator \t Vertical Bar | Comma , Slash / Backslash \ You can choose any other character by setting the variable directly. example: let g:tmSeparator = "#" ----------------------------------------------------------------------------- 5.3 Colors *treemap-configure-color* global variable: g:tmColor A list with three values. The values are colors. You can choice all possible colors. example: let g:tmColor = ["blue","grey","yellow"] global variable: g:tmVal2Interval Default value: 20.00 The interval in percent (%) for colorization if there is a second numeric value column. See also |treemap-colorization|. The colors are different in the domains: * < "g:tmVal2Average - (g:tmVal2Average * g:tmVal2Interval / 100)" * >= "g:tmVal2Average - (g:tmVal2Average * g:tmVal2Interval / 100)" && <= "g:tmVal2Average + (g:tmVal2Average * g:tmVal2Interval / 100)" * > "g:tmVal2Average + (g:tmVal2Average * g:tmVal2Interval / 100)" The interval could only changed by setting the variable directly: let g:tmVal2Interval = 30.00 +-------------------------------------------------------+ |Note: | |By changing the variable g:tmVal2Interval please always| |specify the value with two decimals. | +-------------------------------------------------------+ global variable: g:tmVal2Average During the generation of the treemap the average of the second numeric value column (if exists) is saved in this variable. ----------------------------------------------------------------------------- 5.4 Size *treemap-configure-size* global variable: g:tmUx & g:tmUy Defines the size of the treemap. g:tmUx -> width / g:tmUy -> height In case of output type "VIM": Width: the number of colums used in the textfile Height: the number of rows used in the textfile In case of output type "SVG": Width: the number of pixels in the SVG graphic Height: the number of pixels in the SVG graphic Default values: VIM: 70 * 25 SVG: 1024 * 768 ----------------------------------------------------------------------------- 5.5 Title *treemap-configure-title* global variable: g:tmTitle Default value: "Treemap" Defines the title of the treemap. In case of output type "VIM": The title is written in line 1 of the output tab In case of output type "SVG": - The title is used in the HTML Header as - The title is used as a headline for the SVG graphic You can set the variable directly: :let g:tmTitle = "My Treemap" ----------------------------------------------------------------------------- 5.6 Logs *treemap-configure-logs* global variable: g:tmVerbose if "g:tmVerbose == 0" only error messages are displayed if "g:tmVerbose == 1" all messages are displayed (includes warnings and informations You can only set this parameter by setting the variabel directly: :let g:tmVerbose = 1 --> default value = 0 global variable: g:tmMess All messages (errors, warnings, informations) of a treemap generation are saved in the this list. You can run the function treemap#drawAllMessages(messages,lang) to print all messages in a new tab. The new tab is generated through the function. Same as |TmLog|. parameter: mess: list of messages (g:tmMess) lang: language example: :call treemap#drawAllMessages(g:tmMess,"EN") ----------------------------------------------------------------------------- 5.7 Clipboard *treemap-configure-clipboard* global variable: g:tmClipboard In case of execute the command TmCreate the calculated rectangles are saved in this variable. The saved rectangles are necessary for using the command TmDraw. This command draw the rectangles of the tmClipboard at the position of your cursor Don't change this variable. global variable: g:tmClipSize Default value: {'x':70,'y':25} Are the rectangles created with the command |TmCreate| the width and height of the generated treemap is saved in this dictionary variable {'x':'width','y':'height'}. This informations are needed for printing the treemap later with |TmDraw|. Don't change this variable. ----------------------------------------------------------------------------- 5.8 Other *treemap-configure-other* global variable: g:tmLayNrs After a treemap generation in the variable g:tmLayers the input entities are saved with their layer number. Example: "Entity 1" : 2 Means that the entity 1 has the layer number 2. Don't change this variable. global variable: g:tmLNr In this variable is the number of layers saved. Don't change this variable. ============================================================================== 6. Menu *treemap-menu* Plugin->Treemap->Run main() Start the treemap generation and call the function treemap#main(output,separator) with the variables g:tmOutput and g:tmSeparator The input window needs a headline! The output is written in a new tab. ----------------------------------------------------------------------------- Plugin->Treemap->Create create() Start the treemap generation and call the function treemap#create(separator) with the variable g:tmSeparator Before starting this command mark an area in visual or visual-block mode. The content of the marked area is the input data for the generation. see |visual-mode| see |visual-block| (Don't select a headline!!) This function only calculates the rectangles and the result is saved in the tmClipboard (g:tmClipboard). The rectangles are not drawn anywhere. +-------------------------------------------------------------+ |Note: | |You start the visual mode with: 'v' |You start the visual block mode with: | | Linux | | Windows | |Then use the keys "h, j, k, l" to mark the area you want to | |select. (Keys: h - , j - , k - , l - )| +-------------------------------------------------------------+ ----------------------------------------------------------------------------- Plugin->Treemap->Draw draw() Start a treemap printing and call the function treemap#draw(output) with the variable g:tmOutput The rectangles that are saved in the tmClipboard are drawn at the current position of your cursor. ----------------------------------------------------------------------------- Plugin->Treemap->Log g:tmMess Create a log file. Print the messages of the variable g:tmMess in a new tab. ----------------------------------------------------------------------------- Plugin->Treemap->Color Defines the colors for the rectangles in the SVG output type mode. You have a choice between triples of colors ----------------------------------------------------------------------------- Plugin->Treemap->Output Type Defines the output type of the treemap - VIM : the treemap is drawn in a new tabulator with the signs "|", "-" and "+" - SVG : the HTML/SVG code of the treemap is printed in a new tabulator. Save this file and open it in a browser. ----------------------------------------------------------------------------- Plugin->Treemap->Separator Defines the character of the separator the input file is separated with Semicolon ; Tabulator \t Vertical Bar | Comma , Slash / Backslash \ ----------------------------------------------------------------------------- Plugin->Treemap->Size Defines the size of the treemap. The width and the height. In case of output type "VIM": Width: the number of colums used in the textfile Height: the number of rows used in the textfile In case of output type "SVG": Width: the number of pixels in the SVG graphic Height: the number of pixels in the SVG graphic ----------------------------------------------------------------------------- Plugin->Treemap->Title Defines the title of the treemap. In case of output type "VIM": The title is written in line 1 of the output tab In case of output type "SVG": - The title is used in the HTML Header as - The title is used as a headline for the SVG graphic ============================================================================== 7. Example *treemap-example* Example for an input file: folder;file;size treemap;treemap.vim;12 treemap;readme.txt;6 xml;xmlcleaner.vim;16 xml;readme.md;7 Example of an output type "VIM": +--------------------------------------------------------------------+ /+----------------------------++------------------------------------+| //+-----------------++-------+//+-----------------------++---------+|| |||treemap.vim /|readme./xt/xmlcleaner.vim //readme.md||| ||| || |||| || ||| ||| || |||| || ||| ||| || |||| || ||| ||| || |||| || ||| ||| || |||| || ||| ||| || |||| || ||| ||| || |||| || ||| ||| || |||| || ||| ||| || |||| || ||| ||| || |||| || ||| ||| || |||| || ||| ||| || |||| || ||| ||| || |||| || ||| //+-----------------++-------+//+-----------------------++---------+|| /+----------------------------++------------------------------------+| +--------------------------------------------------------------------+ Example of an output type "SVG": Treemap

Treemap

Treemap generierte Treemap treemap xml treemap.vim readme.txt xmlcleaner.vim readme.md ============================================================================== 8. Colorization *treemap-colorization* Only in the output type "SVG" rectangles get a color: * If there is only one column with values, the first column fixes the color of all child rectangles * If there is a second column with values, the second value fixes the color of the rectangle (Heat Map) More details to the second case (default values): * the value in the second value column is < 20% of the avarage of the second value column, the color of the rectangle is blue * the value in the second value column is >= 20% or <= 20% of the avarage of the second value column, the color of the rectangle is grey * the value in the second value column is > 20% of the avarage of the second value column, the color of the rectangle is red You can change the colors in the global array 'g:tmColor': :let g:tmColor = ['blue','grey','red'] OR in the Menu "Plugin -> Treemap -> Color" (|treemap-menu|) You can change the percentage of the borders in the global variable 'g:tmVal2Interval: :let g:tmVal2Interval = 20.00 !! Please always specify the value with two decimals !! See also |treemap-configure-color|. ============================================================================== 9. Message Handling *treemap-message* Definition of errors, informations and warnings Errors: *E0001* E0001 DE "Anzahl Ebenen nicht korrekt" EN "Number of layers are incorrect" Def: At least one row has not enough columns. Check your input file. Example of a wrong input file: folder ;file ;size | line 1 Treemap;treemap.vim;7 | line 2 Treemap;treemap.txt;6 | line 3 XML ;xmltest.xml | line 4 XML ;xmltest.txt;7 | line 5 In this case line 4 is one column too short. *E0002* E0002 DE "Das Programm musste aufgrund eines Fehlers abgebrochen werden" EN "The program was interupted cause of errors" Def: There was an error. Because of this error the program has to be stopped. Check the global variable g:tmMess. See also |treemap-configure-logs| |treemap-menu| *E0003* E0003 DE "Der letzte Eintrag ist kein numerischer Wert" EN "The last entry is no numeric value" Def: The last entry in every row (without the headline) must be a numeric value. Check your numeric values. +-----------------------------------------------+ |Note: | |The decimal separator is "." in every language.| +-----------------------------------------------+ Example of a wrong input file: folder ;file ;size | line 1 Treemap;treemap.vim;7 | line 2 Treemap;treemap.txt;6 | line 3 XML ;xmltest.xml;testval | line 4 XML ;treemap.txt;7,2 | line 5 In this case line 4 and 5 have not a numeric value. Line 4: testval is not a numeric value Line 5: 7,2 is not a numeric value (decimal separator: ".") +------------------------------------------------------------+ | Note: | | This error occurs also when you choose a wrong separator | | for the input file. | | See also |treemap-configure-separator| | +------------------------------------------------------------+ *E0004* E0004 DE "Der Rahmen ist zu klein" EN "Frame is too small" Def: The size of the treemap is too small. Check the height and width. See |treemap-configure-size| *E0005* E0005 DE "Jede Einheit darf nur einer übergeordneten Einheit zugeordnet sein" EN "Every unit must have only one parent" Def: Every unit in the input file must have only one parent. Check your input file. Example of a wrong input file: folder ;file ;size | line 1 Treemap;treemap.vim;7 | line 2 Treemap;treemap.txt;6 | line 3 XML ;xmltest.xml;4 | line 4 XML ;treemap.txt;7 | line 5 In this case treemap.txt has two parents. See line 3 and 5. In line 3 the parent of treemap.txt is Treemap. In line 5 the parent of treemap.txt is XML. *E0006* E0006 DE "Für diese Funktion (TmCreate) muss ein Bereich markiert sein" EN "This function need a marked area" Def: The function treemap#create(separator) or the VIM Command TmCreate need a marked area in visual mode or visual-block mode. (Select no headline in the visual marked area!!) see |visual-mode| see |visual-block| *E0007* E0007 DE "Es sind keine Daten im Zwischenspeicher zum zeichnen vorhanden" EN "There are no data to draw in the clipboard" Def: There are no data to draw in the clipboard (g:tmClipboard). Please start first TmCreate to fill the clipboard with data. See |TmCreate| and |TmDraw|. Warnings: *W0001* W0001 DE "Das Rechteck wird nicht gezeichnet, da Fläche zu gering" EN "The rectangle is not drawn because the area is too small" Def: Is the value of an unit is too small, so that the size of the relevant rectangle is smaller than 3*3 (hight*width) the rectangle is not drawn. This has no influence to the other rectangles. Informations: *I0001* I0001 DE "Die Inputparameter sind korrekt" EN "Input paramter are correct" Def: All checks of the input parameters are correct. *I0002* I0002 DE "Die Parameter wurden erfolgreich eingelesen" EN "Parameter read successfull" Def: The input parameters of the input file are now ready for processing. *I0003* I0003 DE "Hierachie wurde aufgebaut und Summen ermittelt" EN "Hierachy set up completed / calculating of sums completed" Def: The hierachy of units are build for further processing. The entries in the input file are summarised. *I0004* I0004 DE "Proportionen wurden ermittelt und Hierachie angereichert" EN "Proportion are calculated and hierachy are enriched" Def: The proportion of the rectangles is calculated. *I0005* I0005 DE "Rechteck wurde gezeichnet" EN "Rectangle is drawn" Def: One rectangle is drawn. *I0006* I0006 DE "Der Rahmen wurde gezeichnet" EN "Frame is drawn" Def: The Frame Rectangle of the treemap is drawn. *I0007* I0007 DE "Jede Einheit bezieht sich auf eine übergerordnete Einheit" EN "Every unit has only one parent" Def: Every unit has only one parent. The error |E0005| did not occur. All messages of a treemap generation run are savesd in the global variable g:tmMess. You can create a log file. To do that read: |treemap-configure-other| |treemap-menu| - Plugin->Treemap->Log g:tmMess ============================================================================== 10. Commands *treemap-commands* For each menu entry there exists a VIM COMMAND (|treemap-menu|): ----------------------------------------------------------------------------- *TmRun* Command: TmRun Start the treemap generation and call the function treemap#main(output,separator) with the variables g:tmOutput and g:tmSeparator The input window needs a headline! The output is written in a new tab. ----------------------------------------------------------------------------- *TmCreate* Command: TmCreate Start the treemap generation and call the function treemap#create(separator) with the variable g:tmSeparator Before starting this command mark an area in visual or visual-block mode. The content of the marked area is the input data for the generation. see |visual-mode| see |visual-block| (Don't select a headline!!) This function only calculates the rectangles and the result is saved in the tmClipboard (g:tmClipboard). The rectangles are not drawn anywhere. +-------------------------------------------------------------+ |Note: | |You start the visual mode with: 'v' | |You start the visual block mode with: | | Linux | | Windows | |Then use the keys "h, j, k, l" to mark the area you want to | |select. (Keys: h - , j - , k - , l - )| +-------------------------------------------------------------+ +--------------------------------------------------------+ |Note: | |If you use the visual-mode, don't use the command | |":TmCreate". You overwrite your data with that. | |Use instead the menu entry "Create" or tc. | |(visual-block mode is no problem) | +--------------------------------------------------------+ ----------------------------------------------------------------------------- *TmDraw* Command: TmDraw Start a treemap drawing and call the function treemap#draw(output) with the variable g:tmOutput The rectangles that are saved in the tmClipboard are drawn at the current position of your cursor. ----------------------------------------------------------------------------- *TmLog* Command: TmLog Create a log file. Print the messages of the variable g:tmMess in a new tab. It calls the function treemap#drawAllMessages(g:tmMess,$lang) ----------------------------------------------------------------------------- *TmColor* Command: TmColor Defines the colors for the rectangles in the SVG output type mode. You have a choice between triples of colors. You have to type in the first color then press [Enter] and so on. ----------------------------------------------------------------------------- *TmOutput* Command: TmOutput Defines the output type of the treemap - VIM : the treemap is drawn in a new tabulator with the signs "|", "-" and "+" - SVG : the HTML/SVG code of the treemap is printed in a new tabulator. Save this file and open it in a browser. ----------------------------------------------------------------------------- *TmSeparator* Command: TmSeparator Defines the character of the separator the input file is separated with Semicolon ; Tabulator \t Vertical Bar | Comma , Slash / Backslash \ and any other character ----------------------------------------------------------------------------- *TmWidth* *TmHeight* Command: TmWidth Command: TmHeight Defines the size of the treemap. The width and the height. In case of output type "VIM": Width: the number of colums used in the textfile Height: the number of rows used in the textfile In case of output type "SVG": Width: the number of pixels in the SVG graphic Height: the number of pixels in the SVG graphic ----------------------------------------------------------------------------- *TmTitle* Command: TmTitle Defines the title of the treemap. In case of output type "VIM": The title is written in line 1 of the output tab In case of output type "SVG": - The title is used in the HTML Header as - The title is used as a headline for the SVG graphic ============================================================================== 11. Mappings *treemap-mappings* For the following menu entries / VIM Commands there exists a Mapping: | Key | Command | ******************************* | tr | |TmRun| | | tc | |TmCreate| | | td | |TmDraw| | | tl | |TmLog| | The is the sign of the variable mapleader. If this variable is not set the leader key is the backslash "\". See also: || example: Type \tr to start the treemap generation (Command :TmRun). ============================================================================== vim:tw=78:fo=tcq2:ts=8:ft=help:norl: plugin/treemap.vim [[[1 1458 " vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " treemap.vim: (plugin) Creates a treemap in a new tab " Last Change: Thu Apr 30 7:45 PM 2015 MET " Author: Data-Statiker " Maintainer: Data-Statiker " Version: 0.9.2, for Vim 7.4+ " New: {{{1 " Version 0.9.2: " * New Commands TmCreate and TmDraw " To seperate the calculating and drawing of treemap " * Create folders in plugin files for a clear view " " Version 0.9.1: " * Add corresponding VIM COMMANDS for each menu entry " * Add Mappings for VIM Commands: " * Set the default width and height in case of Output Type 'VIM' " to 70*25 " " Version 0.9: " * Title for the treemap " * Initialize g:tmMess / no error occurs by starting "print log" " * Namespace for treemap global variables: g:tm* " To avoid incompatibility to other plugins " * Small changes in the help file " " Version 0.8: " * Introduce the global variables g:tmUx and g:tmUy to set the size from the " treemap. So the size of the treemap could be changed throug the variables: " g:tmUx = width " g:tmUy = height " * Adapt the menu to set the height and width of the treemap " * Adapt the menu for printing the log variable g:tmMess " * Update VIM help file " * For some parameters in the function treemap#initialize() " Only set the variables when they do not exist " * New function treemap#checkChildParentRelation(matrix,val2Active) " Check if every unit has only one parent " " Version 0.7: " * In version 0.7 the output paramater is created for the function " treemap#main(). The paramater output could have the values "VIM" or " "SVG". " VIM: Rectangles are created in a new tab with the signs "-", "|" and "+" " SVG: Rectangles are descripted in a SVG structure imbedded in a html " file " * New function treemap#initialize for initializing global variables " * New parameter separator for the method treemap#main(). So the input " file could be separated by ";" or "\t" (tab) or any other signs. The values " of these parameter are for example: " ; for semicolon separated files " \t for tabulator separated files " Examples: :call treemap#main('VIM',';') " :call treemap#main('SVG','\t') " * Insert 'throw "oops"' in treemap#interruptRun() so the program stops " in case of error " * Create the menu "Plugin - Treemap" tor run the script and set the " variables g:tmSeparator, g:tmOutput, g:tmColor " " Version 0.6: " * Delete not used functions "treemap#reorgHierachy" and "treemap#reorgHierachy2" with " all sub functions " * Rename function "treemap#reorgHierachy3" to "treemap#reorgHierachy" " * Add a second value column. This value is represented in the treemap through " colors (Heat Map). Only SVG-Output. If ther is no val 2 column, the layer 1 " entries define the color of their childs " " Version 0.5: " * In version 0.5 the recursive function "treemap#reorgHierachy2" is substitute " through the iterative function "treemap#reorgHierachy3" " * SVG-Output with fill color " Variable Definition {{{1 " fill colors for Rectangles :let g:tmColor = ['blue','grey','red'] " initialize g:tmSeparator :let g:tmSeparator = "\\t" " initialize g:tmOutput :let g:tmOutput = 'VIM' " list for warnings and errors :let g:tmMess = [] :let g:tmErr = 0 " initialize global variables :function! treemap#initialize() " frame data / will be defined in the main() function ":let g:tmX = 230 ":let g:tmY = 65 ":let g:tmX = 1024 ":let g:tmY = 768 ":let g:tmPt = g:tmX * g:tmY " val2 average and interval values / is val2 active or not :let g:tmVal2Active = "false" :let g:tmVal2Average = 0.00 :if !exists("g:tmVal2Interval") :let g:tmVal2Interval = 20.00 :endif " fill colors for Rectangles color index :let g:tmCIndex = 0 " number of layers :let g:tmLNr = 0 :let g:tmLayNrs = [] " actual tabpage " :let g:tmTabMain = tabpagenr() " verbose - all messenges are displayed if g:tmVerbose = 1 :if !exists("g:tmVerbose") :let g:tmVerbose = 0 :endif " Hierachy flat :let g:tmTrHier = [] " Title for the treemap :if !exists("g:tmTitle") :let g:tmTitle = "Treemap" :endif " Clipboard variables :if !exists("g:tmClipboard") :let g:tmClipboard = [] :endif :if !exists("g:tmClipSize") :let g:tmClipSize = {} :endif " list for warnings and errors :let g:tmMess = [] :let g:tmErr = 0 " Definition of errors, informations and warnings " Errors :let g:tmE0001 = {"T":"E","O":"A","DE":"|E|E0001|Anzahl Ebenen nicht korrekt"} :let g:tmE0001["EN"] = "|E|E0001|Number of layers are incorrect" :let g:tmE0002 = {"T":"E","O":"A","DE":"|E|E0002|Das Programm musste aufgrund eines Fehlers abgebrochen werden"} :let g:tmE0002["EN"] = "|E|E0002|The program was interupted cause of errors" :let g:tmE0003 = {"T":"E","O":"A","DE":"|E|E0003|Der letzte Eintrag ist kein numerischer Wert"} :let g:tmE0003["EN"] = "|E|E0003|The last entry is no numeric value" :let g:tmE0004 = {"T":"E","O":"A","DE":"|E|E0004|Der Rahmen ist zu klein"} :let g:tmE0004["EN"] = "|E|E0004|Frame is too small" :let g:tmE0005 = {"T":"E","O":"A","DE":"|E|E0005|Jede Einheit darf nur einer übergeordneten Einheit zugeordnet sein"} :let g:tmE0005["EN"] = "|E|E0005|Every unit must have only one parent" :let g:tmE0006 = {"T":"E","O":"A","DE":"|E|E0006|Für diese Funktion (TmCreate) muss ein Bereich markiert sein"} :let g:tmE0006["EN"] = "|E|E0006|This function need a marked area" :let g:tmE0007 = {"T":"E","O":"A","DE":"|E|E0007|Es sind keine Daten im Zwischenspeicher zum zeichnen vorhanden"} :let g:tmE0007["EN"] = "|E|E0007|There are no data to draw in the clipboard" " Warnings :let g:tmW0001 = {"T":"W","O":"A","DE":"|W|W0001|Das Rechteck wird nicht gezeichnet, da Fläche zu gering"} :let g:tmW0001["EN"] = "|W|W0001|The rectangle is not drawn because the area is too small" " Informations :let g:tmI0001 = {"T":"I","O":"A","DE":"|I|I0001|Die Inputparameter sind korrekt"} :let g:tmI0001["EN"] = "|I|I0001|Input paramter are correct" :let g:tmI0002 = {"T":"I","O":"A","DE":"|I|I0002|Die Parameter wurden erfolgreich eingelesen"} :let g:tmI0002["EN"] = "|I|I0002|Parameter read successfull" :let g:tmI0003 = {"T":"I","O":"A","DE":"|I|I0003|Hierachie wurde aufgebaut und Summen ermittelt"} :let g:tmI0003["EN"] = "|I|I0003|Hierachy set up completed / calculating of sums completed" :let g:tmI0004 = {"T":"I","O":"A","DE":"|I|I0004|Proportionen wurden ermittelt und Hierachie angereichert"} :let g:tmI0004["EN"] = "|I|I0004|Proportion are calculated and hierachy are enriched" :let g:tmI0005 = {"T":"I","O":"A","DE":"|I|I0005|Rechteck wurde gezeichnet"} :let g:tmI0005["EN"] = "|I|I0005|Rectangle is drawn" :let g:tmI0006 = {"T":"I","O":"A","DE":"|I|I0006|Der Rahmen wurde gezeichnet"} :let g:tmI0006["EN"] = "|I|I0006|Frame is drawn" :let g:tmI0007 = {"T":"I","O":"A","DE":"|I|I0007|Jede Einheit bezieht sich auf eine übergerordnete Einheit"} :let g:tmI0007["EN"] = "|I|I0007|Every unit has only one parent" :endf " Object Rectangle {{{1 " returns an object of type rectangle :function! treemap#rectangle (posx,posy,lenx,leny) :let rec = {} :let rec = {'x':a:posx,'y':a:posy,'lx':a:lenx,'ly':a:leny} " Daten aus Objekt rec holen " :let positionx = get(rec,'x') :return rec :endf " Read & Check Input Data {{{1 " data are read out of the window and return the values as a double list " (matrix) :function! treemap#readScreen(separator,area) :let notes = [] :let err = 0 :if a:area == 'block' "input data are from a visual block :execute 'normal gv"ay' :let buffer = split(@a,"\n") " insert first line (headline) :let tmTemp = split(buffer[0],"\t") :let tmHeadline = "" :let tmI = 0 :for item in tmTemp :let tmI += 1 :let tmHeadline = tmHeadline."Head" :if tmI < len(tmTemp) :let tmHeadline = tmHeadline."\t" :endif :endfor :call insert(buffer,tmHeadline,0) :else " a:area == file :let buffer = getline(1,line("$")) :endif :let screen = [] :let i = 0 :for i in range(0,len(buffer)-1) :call add(screen,split(buffer[i],a:separator)) :endfor :unlet i :unlet buffer :call treemap#checkInput(screen) :if (err == 0) :call add(notes,[g:tmI0002,""]) :if g:tmVal2Active == "true" :call treemap#calculateVal2Average(screen) :endif :endif :call treemap#printMessage(notes) :if (err == 1) :call treemap#interruptRun(err) :endif :call treemap#fillMessage(notes) :unlet notes :unlet err :return screen :endf " calculate the average value of all val2 values and set global variable g:tmVal2Average :function! treemap#calculateVal2Average(screen) :let sum = 0.00 :let i = 0 :for item in a:screen :if i == 0 :let i += 1 :else :let sum += item[len(item)-1] :endif :endfor :let g:tmVal2Average = sum / (len(a:screen)-1) :unlet sum :endf " checks about the read data of the screen :function! treemap#checkInput(screen) :let notes = [] :let err = 0 :let layerNr = len(a:screen[0]) :let err = 0 :let i = 0 :for i in range(0,len(a:screen)-1) :let li = i+1 " are numbers of elements in every row correct? :try :if len(a:screen[i]) != layerNr :call add(notes,[g:tmE0001,"Zeile: ".li]) :let err = 1 :endif :catch /^Vim\%((\a\+)\)\=:E/ :call add(notes,[g:tmE0001,"Zeile: ".li]) :let err = 1 :endtry " is in all rows the last column a value :try :if !(a:screen[i][layerNr-1] =~ str2nr(a:screen[i][layerNr-1])) :if i > 0 :call add(notes,[g:tmE0003,"Zeile: ".li]) :let err = 1 :endif :endif :catch /^Vim\%((\a\+)\)\=:E/ :let err = 1 :endtry " is in all rows the column before the last column a value :if a:screen[1][layerNr-2] =~ str2nr(a:screen[i][layerNr-2]) :let g:tmVal2Active = "true" :try :if !(a:screen[i][layerNr-2] =~ str2nr(a:screen[i][layerNr-2])) :if i > 0 :call add(notes,[g:tmE0003,"Zeile: ".li]) :let err = 1 :endif :endif :catch /^Vim\%((\a\+)\)\=:E/ :let err = 1 :endtry :endif :unlet li :endfor :unlet i :call treemap#checkChildParentRelation(a:screen,g:tmVal2Active) :if (err == 0) :call add(notes,[g:tmI0001,""]) :endif :call treemap#fillMessage(notes) :call treemap#printMessage(notes) :call treemap#interruptRun(err) :unlet layerNr :unlet err :return notes :endf :function! treemap#checkChildParentRelation(matrix,val2Active) :let notes = [] :let err = 0 :if a:val2Active == "false" :let layerNr = len(a:matrix[0])-1 :else :let layerNr = len(a:matrix[0])-2 :endif :if layerNr > 1 :let i = 1 :for i in range(1,layerNr-1) :let column = layerNr-i :let a = 0 :for item in a:matrix :if a == 0 :let a = 1 :continue :endif :let checkUnit = item[column] :let checkParent = item[column-1] :let b = 0 :for unit in a:matrix :if b == 0 :let b = 1 :continue :endif :if unit[column] == checkUnit :if unit[column-1] != checkParent :let err = 1 :call add(notes,[g:tmE0005,checkUnit." - ".checkParent]) :endif :endif :endfor :unlet b :endfor :unlet a :let i += 1 :endfor :unlet i :endif :if err == 0 :call add(notes,[g:tmI0007,""]) :endif :call treemap#fillMessage(notes) :call treemap#printMessage(notes) :call treemap#interruptRun(err) :endf " units list: entries are dictioniaries: layer, description, value, sum :function! treemap#createHierachy(screen) :let notes = [] :let err = 0 :let hierachy = [] :let layerNr = len(a:screen[0]) :if g:tmVal2Active == "true" :let diff = 3 :else :let diff = 2 :endif :let i = 0 :for i in range(0,layerNr-diff) :let layerElements = treemap#groupBy(a:screen,i) :let a = 0 :for a in range(0,len(layerElements)-1) :let entry = {} :let entry = {"layer":i,"desc":layerElements[a][0],"parent":layerElements[a][1]} " add value column 2 to last layer entries :if g:tmVal2Active == "true" :if entry.layer == layerNr-3 :let entry["val2"] = treemap#getVal2(a:screen,entry.desc) :endif :endif :let sum = treemap#calculateSum(layerElements[a][0],a:screen,i) :let entry["sum"] = sum :unlet sum :call add(hierachy,entry) :unlet entry :endfor :unlet a :unlet layerElements :endfor :unlet i :if (err == 0) :call add(notes,[g:tmI0003,""]) :endif :if (err == 1) :call treemap#interruptRun(err) :endif :call treemap#fillMessage(notes) :call treemap#printMessage(notes) :unlet notes :unlet err :unlet layerNr :unlet diff :let hierachy = treemap#enrichProportion(hierachy) :let g:tmTrHier = hierachy :return hierachy :endf :function! treemap#getVal2(screen,lastLayerDesc) :let val2 = 0.00 :let layerNr = len(a:screen[1])-3 :if !exists("a:screen[1][layerNr+2") :for item in a:screen :if item[layerNr] == a:lastLayerDesc :let val2 = item[layerNr+2] + 0.00 :endif :endfor :endif :unlet layerNr :return val2 :endf :function! treemap#reorgHierachy(hierachy) :let layerNr = treemap#getLayerNr(a:hierachy) :let collector = [] :let i = 0 :for i in range(0,layerNr-1) :let parents = treemap#getAllParentsPerLayer(a:hierachy,i) :let container = {} :for p in parents :let container[p] = [] :endfor :for item in a:hierachy :if item.layer == i :for unit in parents :if item.parent == unit || (item.parent == "" && unit == 'FRAME') :call add(container[unit],item) :endif :endfor :endif :endfor :call add(collector,container) :unlet container :endfor :unlet i :let i = layerNr-1 :while i > 0 :for key in keys(collector[i]) :for item in collector[i][key] :if i == item.layer :if !exists("item.childs") :let item["childs"] = [] :endif :for key2 in keys(collector[i-1]) :for pa in collector[i-1][key2] :if !exists("pa.childs") :let pa["childs"] = [] :endif :if item.parent == pa.desc :call add(pa["childs"],item) :endif :endfor :endfor :endif :endfor :endfor :let i -= 1 :endwhile :unlet i :let collector2 = collector[0].FRAME :for item in collector2 :if !exists("item.childs") :let item["childs"] = [] :endif :endfor :return collector2 :endf " Functions Utilities {{{1 :function! treemap#getAllParentsPerLayer(hierachy,layerNr) :let parents = [] :for item in a:hierachy :if item.layer == a:layerNr :let exists_ = "" :for p in parents :if p == item.parent :let exists_ = 'X' :break :endif :endfor :if exists_ != "X" :call add(parents,item.parent) :endif :endif :endfor :if parents[0] == "" :let parents[0] = "FRAME" :endif :return parents :endf :function! treemap#getDescEntry(p,hierachy) :for item in a:hierachy :if item.desc == a:p :let entry = item :endif :endfor :return entry :endf :function! treemap#getParents(hierachy,layerNr) :let temp = [] :let parents = [] :for item in a:hierachy :if item.layer == a:layerNr :call add(temp,item) :endif :endfor :let parentTemp = '' :let exist = '' :for unit in temp :let parentTemp = unit.desc :for p in parents :if p == parentTemp :let exist = 'X' :endif :endfor :if exist != 'X' :call add(parents,parentTemp) :endif :let exist = '' :endfor :return parents :endf " break run when an error occur :function! treemap#interruptRun(err) :let notes = [] :if a:err == 1 :call add(notes,[g:tmE0002,""]) :call treemap#fillMessage(notes) :call treemap#printMessage(notes) :let g:tmErr = 1 :sleep 10 :throw "oops" ":exit :endif :unlet notes :endf " print protocol messages :function! treemap#printMessage(notes) :let language = $lang :let i = 0 :for i in range(0,len(a:notes)-1) :if language == "DE" :if a:notes[i][0].T == "E" echohl = ErrorMsg | echom a:notes[i][0].DE ." / ". a:notes[i][1] | echohl = None :elseif g:tmVerbose == 1 echom a:notes[i][0].DE ." ". a:notes[i][1] :endif :else :if a:notes[i][0].T == "E" echohl = ErrorMsg | echom a:notes[i][0].EN ." / ". a:notes[i][1] | echohl = None :elseif g:tmVerbose == 1 echom a:notes[i][0].EN ." ". a:notes[i][1] :endif :endif :endfor :unlet i :unlet language :endf " delete double entries in a column of a list (matrix) :function! treemap#groupBy(buffer,column) :let output = [] :let outputAll = [] :let i = 1 :for i in range(1,len(a:buffer)-1) :let exists = " " :let a = 0 :for a in range(0,len(output)-1) :if (a:buffer[i][a:column] == output[a]) :let exists = "X" :break :endif :endfor :unlet a :let parentID = 0 :if a:column > 0 let parentID = a:column-1 :endif :if exists != "X" :if a:column > 0 :call add(output,a:buffer[i][a:column]) :call add(outputAll,[a:buffer[i][a:column],a:buffer[i][parentID]]) :else :call add(output,a:buffer[i][a:column]) :call add(outputAll,[a:buffer[i][a:column],'']) :endif :endif :unlet exists :endfor :unlet i :unlet output :return outputAll :endf " calculate sum the element of a layer X :function! treemap#calculateSum(element,matrix,column) :if g:tmVal2Active == 'true' :let diff = 2 :else :let diff = 1 :endif :let sum = 0.00000 :let layerNr = len(a:matrix[0]) :let z = 0 :for z in range(0,len(a:matrix)-1) :if a:matrix[z][a:column] == a:element let sum += a:matrix[z][layerNr-diff] :endif :endfor :unlet z :unlet diff :return sum :endf " enrich hierarchy data with the proportion :function! treemap#enrichProportion(hierachy) :let notes = [] :let err = 0 "calculate sum ":for key in keys(a:hierachy) " : ":endfor :let sum = 0.0 :let item = {} :for item in a:hierachy :if item.layer == 0 :let sum += item.sum :endif :endfor :unlet item " calculate proportion and enrich data :let i = 0 :for i in range (0,len(a:hierachy)-1) :let prop = a:hierachy[i].sum * 100 / sum :let a:hierachy[i]["prop"] = prop :let pt = g:tmPt * prop / 100 :let a:hierachy[i]["pt"] = pt :unlet prop :unlet pt :endfor :unlet i :if (err == 0) :call add(notes,[g:tmI0004,""]) :endif :call treemap#fillMessage(notes) :call treemap#printMessage(notes) :call treemap#interruptRun(err) :unlet err :unlet notes return a:hierachy :endf :function! treemap#fillMessage(notes) :if !empty(a:notes) :for note in a:notes :call add(g:tmMess,note) :endfor :endif :endf " determine the number of layers :function! treemap#getLayerNr(hierachy) :if g:tmLNr == 0 :let max = 0 :for item in a:hierachy :if item.layer > max :let max = item.layer :endif :endfor :let g:tmLNr = max+1 :endif :return g:tmLNr :endf " determine the layer number of a special entry :function! treemap#getLayerNrDesc(desc,hierachy) :let layer = -1 :for item in a:hierachy :if item.desc == a:desc :let layer = item.layer :break :endif :endfor :call add(g:tmLayNrs,a:desc.': '.layer) :return layer :endf " Print all messages from g:tmMess :function! treemap#printAllMessages(messages,lang) :if a:lang == 'DE' || a:lang == 'EN' :tabnew :let i = 0 :for item in a:messages :let i+= 1 :call setline(i,item[0][a:lang].' / '.item[1]) :endfor :unlet i :else :echo 'Die Sprache '.a:lang.' ist nicht gepflegt!' :endif :endf " open the treemap in a browser and save it if not done before ":function! treemap#openSVG() " :let tmFileName = expand(@%) " :if tmFileName == "" " :if exists("*mkdir") " :call mkdir($HOME . "\treemaps", "p","") " :endif " :execute 'normal w '.$home.'treemaps\treemap.htm' " :let tmFileName = expand(@%) " :endif " :let tmFileName = substitute(tmFileName,"\\","\/","g") " :execute 'silent ! start "Title" /b file:///'.tmFileName ":endf " Print Treemap {{{1 " Draw Frame :function! treemap#drawFrame(column,line) :let notes = [] :let err = 0 :if (g:tmX > 1) && (g:tmY > 1) :call setpos(".",[0,a:line,1,0]) :let a = 0 :for a in range (0,g:tmY+1) :execute "normal i\\" :execute "normal k" :let i = 0 :for i in range (0,g:tmX+1+a:column) :execute "normal i \" :endfor :unlet i :endfor :unlet a :let frame = treemap#rectangle(a:column,a:line,g:tmX,g:tmY) :let frame.title = 'FRAME' :call treemap#drawRectangle(frame) :else :call add(notes,[g:tmE0004,""]) :let err = 1 :endif :if (err == 0) :call add(notes,[g:tmI0006,""]) :endif :call treemap#fillMessage(notes) :call treemap#printMessage(notes) :call treemap#interruptRun(err) :unlet err :unlet notes :endf " Draw a rectangle :function! treemap#drawRectangle(rec) :let notes = [] :let err = 0 :if (a:rec.lx > 1) && (a:rec.ly > 1) " set corner points :call setpos(".",[0,a:rec.y,a:rec.x,0]) :execute "normal r+\" :call setpos(".",[0,a:rec.y,a:rec.x+a:rec.lx-1,0]) :execute "normal r+\" :call setpos(".",[0,a:rec.y+a:rec.ly-1,a:rec.x,0]) :execute "normal r+\" :call setpos(".",[0,a:rec.y+a:rec.ly-1,a:rec.x+a:rec.lx-1,0]) :execute "normal r+\" " set description :let i = 1 :for i in range(1,strlen(a:rec.title)) :call setpos(".",[0,a:rec.y+1,a:rec.x+i,0]) :execute "normal r".strpart(a:rec.title,i-1,1)."\" :endfor :unlet i " paint horizontal 1 :let i = 1 :for i in range(1,a:rec.lx-2) :call setpos(".",[0,a:rec.y,a:rec.x+i,0]) :execute "normal r-\" :endfor :unlet i :redraw ":call input("Type [ENTER] to go further") " paint vertical 1 :let i = 1 :for i in range(1,a:rec.ly-2) :call setpos(".",[0,a:rec.y+i,a:rec.x,0]) :execute "normal r|\" :endfor :unlet i :redraw ":call input("Type [ENTER] to go further") " paint horizontal 2 :let i = 1 :for i in range(1,a:rec.lx-2) :call setpos(".",[0,a:rec.y+a:rec.ly-1,a:rec.x+i,0]) :execute "normal r-\" :endfor :unlet i :redraw ":call input("Type [ENTER] to go further") " paint vertical 2 :let i = 1 :for i in range(1,a:rec.ly-2) :call setpos(".",[0,a:rec.y+i,a:rec.x+a:rec.lx-1,0]) :execute "normal r|\" :endfor :unlet i :redraw ":call input("Type [ENTER] to go further") :redraw :else :call add(notes,[g:tmW0001,a:rec.title]) :endif :if (err == 0) :call add(notes,[g:tmI0005,a:rec.title]) :endif :call treemap#fillMessage(notes) :call treemap#printMessage(notes) :call treemap#interruptRun(err) :unlet err :unlet notes :endf " SVG Output :function! treemap#drawRectanglesSVG(rectangles) " HTML part 1 :call setline(1,'') :call setline(2,'') :call setline(3,'') :call setline(4,''.g:tmTitle.'') :call setline(5,'') :call setline(6,'') :call setline(7,'

'.g:tmTitle.'

') " SVG ":call setline(8,'') ":call setline(9,'') :call setline(8,'') :call setline(9,''.g:tmTitle.'') :call setline(10,'powered by TREEMAP VIM PLUGIN') :let i = 11 :for item in a:rectangles :if (item.lx > 1) && (item.ly > 1) :call setline(i,'') :let i+= 1 :let p1 = item.x+10 :let p2 = item.y+20 :call setline(i,''.item.title.'') :unlet p1 :unlet p2 :let i+= 1 :endif :endfor :call setline(i,'') " HTML part 2 :call setline(i+1,'') :call setline(i+2,'') :unlet i :endf " Main Function {{{1 " main function to run the treemap algorithm :function! treemap#main(output,separator) :call treemap#initialize() :let g:tmCIndex = 0 " Output = VIM / set frame variables :if a:output == 'VIM' :if exists("g:tmUx") && exists("g:tmUy") :let g:tmX = g:tmUx :let g:tmY = g:tmUy :else :let g:tmX = 70 :let g:tmY = 25 :endif :let g:tmPt = g:tmX * g:tmY :endif " Output = SVG / set frame variables :if a:output == 'SVG' :if exists("g:tmUx") && exists("g:tmUy") :let g:tmX = g:tmUx :let g:tmY = g:tmUy :else :let g:tmX = 1024 :let g:tmY = 768 :endif :let g:tmPt = g:tmX * g:tmY :endif :let screen = treemap#readScreen(a:separator,"file") :let hier = treemap#createHierachy(screen) :let nestedHier = treemap#reorgHierachy(hier) :let recs = treemap#sliceAndDice(nestedHier) :tabnew " Output = VIM / print rectangles (text) :if a:output == 'VIM' :call treemap#drawFrame(1,1) :for item in recs :call treemap#drawRectangle(item) :endfor :execute "normal" "gg" :execute "normal" "O" :call setline(1,g:tmTitle) :endif " Output = SVG / print rectangles SVG :if a:output == 'SVG' :call treemap#drawRectanglesSVG(recs) :endif :endf " Only create the rectangles of a treemap, but don't print it :function! treemap#create(separator) "set width and height :if exists("g:tmUx") && exists("g:tmUy") :let g:tmX = g:tmUx :let g:tmY = g:tmUy :else :let g:tmX = 70 :let g:tmY = 25 :endif :let g:tmPt = g:tmX * g:tmY :call treemap#initialize() :let notes = [] :let err = 0 " check if a visual-block is active :if char2nr(visualmode()) != 22 && visualmode() != 'v' :call add(notes,[g:tmE0006,""]) :let err = 1 :call treemap#fillMessage(notes) :call treemap#printMessage(notes) :call treemap#interruptRun(err) :endif :let screen = treemap#readScreen(a:separator,"block") :let hier = treemap#createHierachy(screen) :let nestedHier = treemap#reorgHierachy(hier) :let recs = treemap#sliceAndDice(nestedHier) " Save the calculated rectangles to the clipboard :let g:tmClipboard = recs :let g:tmClipSize = {'x':g:tmX,'y':g:tmY} :endf " draw the treemap at the position of your cursor :function! treemap#draw(output) :let notes = [] :let err = 0 :call treemap#initialize() :if empty(g:tmClipboard) || empty(g:tmClipSize) :call add(notes,[g:tmE0007,""]) :let err = 1 :call treemap#fillMessage(notes) :call treemap#printMessage(notes) :call treemap#interruptRun(err) :endif :let s:tmRecs = [] " read width and height from g:tmClipSize :let g:tmX = g:tmClipSize.x :let g:tmY = g:tmClipSize.y :let s:tmRecs = deepcopy(g:tmClipboard) " Output = VIM / print rectangles (text) :if a:output == 'VIM' :let s:tmPos = getpos(".") :let s:lnum = s:tmPos[1] :let s:col = s:tmPos[2] :call treemap#drawFrame(s:col,s:lnum) :for item in s:tmRecs :let item.x = item.x + s:col-1 :let item.y = item.y + s:lnum-1 :call treemap#drawRectangle(item) :endfor :endif " Output = SVG / print rectangles SVG :if a:output == 'SVG' :tabnew :call treemap#drawRectanglesSVG(g:tmClipboard) :endif :endf " Calculate the Rectangles {{{1 " Treemap algorithm Slice and Dice :function! treemap#sliceAndDice(hierachy) :let rectangles = [] :let root = treemap#rectangle(1,1,g:tmX,g:tmY) :let root.title = 'FRAME' :let root.fill = '' :let root.layer = -1 :let recs = treemap#getRectangles(root,a:hierachy) :for t in recs :call add(rectangles,t) :endfor :return rectangles :endf :function! treemap#getRectangles(root,hierachy) :let rectangles = [] :let recs = treemap#getSubRectangles(a:root,a:hierachy) :for t in recs :call add(rectangles,t) :endfor :for item in a:hierachy :let unit = [] :let unit = treemap#getChilds(item.desc,a:hierachy) :if !empty(unit) :let recRoot = treemap#getRootRectangle(item.desc,rectangles) ":echo 'Root Rectangle// Laenge: '.recRoot.lx.' Hoehe: '.recRoot.ly :let r = treemap#getRectangles(recRoot,unit) :for re in r :call add(rectangles,re) :endfor :endif :endfor :return rectangles :endf :function! treemap#getRootRectangle(desc,rectangles) :let recRoot = {} :let hit = '' :for re in a:rectangles :if hit == 'X' :break :endif :if re.title == a:desc :let recRoot = re :let hit = 'X' :endif :endfor :return recRoot :endf :function! treemap#getChilds(unit,hierachy) :let collector = [] :for item in a:hierachy :for it in item.childs " :echo a:unit :if it.parent == a:unit :call add(collector,it) " :echo 'Child: '.it.desc :endif :endfor ":echo '***************' :endfor ":echo '***********************************************' :return collector :endf " Get Hierachy Entry or FRAME :function! treemap#getHierachyEntry(unit,hierachy) :let collector = {} :let sum = 0 :for item in a:hierachy :if a:unit == 'FRAME' :let collector['desc'] = 'FRAME' :for it in a:hierachy :if it.layer == 0 :let sum += it.sum :endif :endfor :let collector['sum'] = sum :break :endif :if item.desc == a:unit :let collector = item :break :endif :endfor :return collector :endf " determine the sub rectangles / Slice and Dice :function! treemap#getSubRectangles(root,childs) :let resultList = [] :let rect = {} :let width = 0 :let actual = 0 :let layer = treemap#getLayerNrDesc(a:childs[0].desc,a:childs) :let rootHier = treemap#getHierachyEntry(a:root.title,g:tmTrHier) :if a:root.ly > a:root.lx :let width = a:root.lx-2 :for child in a:childs " determine Color :let rFill = '' :let val2 = 0 :if g:tmVal2Active == 'true' :if child.layer == treemap#getLayerNr(g:tmTrHier)-1 :let val2 = child.val2 :endif :endif :let rFill = treemap#getColor(val2,a:root.layer,child.layer) :let rect = {} :let rect.x = a:root.x+1 :let rect.y = a:root.y+actual+1 :let rect.lx = width :let rect.ly = float2nr(round((a:root.ly-2.00)*((child.sum*100.00)/rootHier.sum)/100.00)) :let actual = actual + rect.ly :let rect.title = child.desc :if rFill == '' :if g:tmVal2Active == 'true' :let rect.fill = 'white' :else :let rect.fill = a:root.fill :endif :else :let rect.fill = rFill :endif :let rect.layer = child.layer :call add (resultList, rect) :endfor :let actual = 0 :else :let hight = a:root.ly-2 :for child in a:childs " determine Color :let rFill = '' :let val2 = 0 :if g:tmVal2Active == 'true' :if child.layer == treemap#getLayerNr(g:tmTrHier)-1 :let val2 = child.val2 :endif :endif :let rFill = treemap#getColor(val2,a:root.layer,child.layer) :let rect = {} :let rect.y = a:root.y+1 :let rect.x = a:root.x+actual+1 :let rect.ly = hight :let rect.lx = float2nr(round((a:root.lx-2.00)*((child.sum*100.00)/rootHier.sum)/100.00)) :let actual = actual + rect.lx :let rect.title = child.desc :if rFill == '' :if g:tmVal2Active == 'true' :let rect.fill = 'white' :else :let rect.fill = a:root.fill :endif :else :let rect.fill = rFill :endif :let rect.layer = child.layer :call add (resultList, rect) :endfor :let actual = 0 :endif :unlet actual :unlet rFill :unlet width :unlet layer :unlet rootHier :unlet rect :return resultList :endf " Colorization :function! treemap#getColor(val2,rootLayer,childLayer) :let fillColor = '' " heat map :if g:tmVal2Active == 'true' && a:childLayer == treemap#getLayerNr(g:tmTrHier)-1 :let fillColor = g:tmColor[1] :if a:val2 < g:tmVal2Average - (g:tmVal2Average * g:tmVal2Interval / 100) :let fillColor = g:tmColor[0] :elseif a:val2 > g:tmVal2Average + (g:tmVal2Average * g:tmVal2Interval / 100) :let fillColor = g:tmColor[2] :else :let fillColor = g:tmColor[1] :endif " one color for one layer 1 entry :elseif g:tmVal2Active == 'false' :if a:rootLayer == -1 :let fillColor = g:tmColor[g:tmCIndex] :if g:tmCIndex < len(g:tmColor)-1 :let g:tmCIndex += 1 :else :let g:tmCIndex = 0 :endif :endif :else :let fillColor = '' :endif :return fillColor :endf