代码之家  ›  专栏  ›  技术社区  ›  Michael

使用什么工具绘制文件树图[已关闭]

  •  68
  • Michael  · 技术社区  · 17 年前

    我更喜欢矢量(SVG、EPS、EMF…)文件。 该工具必须在Windows上运行,但最好是跨平台运行。 该工具可以是商用的,但最好是免费的。

    在抓屏之前,我必须将前景色修改为黑色,将背景色修改为白色,以便在打印的文档中看起来更好并节省墨水。

    2017年10月17日更新。 很抱歉,此问题因不属于SO而被删除。所以我重新措辞了。我需要一个脚本,而不是所见即所得工具。所以任何脚本语言或库都可以。因此,这是一个代码编写问题,我相信属于So。

    5 回复  |  直到 6 年前
        1
  •  118
  •   KiriSakow    8 年前

    从MS-DOS复制和粘贴 tree 命令可能也适用于您。示例:

    C:\Foobar>tree
    C:.
    ├───FooScripts
    ├───barconfig
    ├───Baz
    │   ├───BadBaz
    │   └───Drop
    ...
    

    树/楼

    C:\Foobar>tree
    C:.
    ├───FooScripts
    │    foo.sh
    ├───barconfig
    │    bar.xml
    ├───Baz
    │   ├───BadBaz
    │   │    badbaz.xml
    │   └───Drop
    ...
    

    C:\Foobar>tree /A
    C:.
    +---FooScripts
    +---barconfig
    +---Baz
    ¦   +---BadBaz
    ¦   \---Drop
    ...
    

    树形图/F/A

    C:\Foobar>tree /A
    C:.
    +---FooScripts
    ¦    foo.sh
    +---barconfig
    ¦    bar.xml
    +---Baz
    ¦   +---BadBaz
    ¦   ¦    badbaz.xml
    ¦   \---Drop
    ...
    

    语法 [ source

    [ drive: ][ path /F /A

    drive:\path 驱动器和目录包含用于显示目录结构的磁盘,不列出文件。

    /F

    /A /a 与不支持图形字符的代码页一起使用,并将输出发送到不正确解释图形字符的打印机。

        2
  •  19
  •   joel.neely    17 年前

    Graphviz -从网页:

    Graphviz布局程序以简单的文本语言对图形进行描述,并以多种有用的格式制作图表,如用于网页的图像和SVG,用于PDF或其他文档的Postscript;或显示在交互式图形浏览器中。(Graphviz还支持GXL,一种XML方言。)

        3
  •  5
  •   paxdiablo    17 年前

    为什么您不能在Windows文件系统上创建一个文件结构并用您想要的名称填充它,然后使用HyperSnap(或无处不在的Alt-PrtScr)之类的屏幕抓取器来捕获资源管理器窗口的一部分呢。

    我在“演示”一个具有可折叠部分的互联网应用程序时就是这样做的,我只需要创建看起来像我想要的条目的文件。

    或者你可以从浏览器中截取图标+/-并在MS Word Draw中使用它们来绘制图片,但我一直无法让MS Word Draw正常工作。

        4
  •  5
  •   PhiLho    17 年前

    正如承诺的,这是我的开罗版本。我用Lua编写了脚本,使用lfs遍历目录。我喜欢这些小挑战,因为它们允许我探索我想挖掘很久的API。。。

    当我在树上行走时,我制作了第一个版本的图形文件名。优点:无内存开销。不便之处:我必须事先指定图像大小,因此列表可能会被切断。

    所以我制作了这个版本,首先遍历目录树,将其存储在Lua表中。然后,知道文件的数量,创建适合的画布(至少垂直),并绘制名称。
    您可以轻松地在PNG渲染和SVG渲染之间切换。后者的问题是:Cairo在低级别生成它,绘制字母,而不是使用SVG的文本功能。至少,即使在没有字体的系统上,它也能保证准确的渲染。但是文件更大。。。如果您在压缩之后使用.svgz文件,那么这并不是一个真正的问题。

    -- LuaFileSystem <http://www.keplerproject.org/luafilesystem/>
    require"lfs"
    -- LuaCairo <http://www.dynaset.org/dogusanh/>
    require"lcairo"
    local CAIRO = cairo
    
    
    local PI = math.pi
    local TWO_PI = 2 * PI
    
    --~ local dirToList = arg[1] or "C:/PrgCmdLine/Graphviz"
    --~ local dirToList = arg[1] or "C:/PrgCmdLine/Tecgraf"
    local dirToList = arg[1] or "C:/PrgCmdLine/tcc"
    -- Ensure path ends with /
    dirToList = string.gsub(dirToList, "([^/])$", "%1/")
    print("Listing: " .. dirToList)
    local fileNb = 0
    
    --~ outputType = 'svg'
    outputType = 'png'
    
    -- dirToList must have a trailing slash
    function ListDirectory(dirToList)
      local dirListing = {}
      for file in lfs.dir(dirToList) do
        if file ~= ".." and file ~= "." then
          local fileAttr = lfs.attributes(dirToList .. file)
          if fileAttr.mode == "directory" then
            dirListing[file] = ListDirectory(dirToList .. file .. '/')
          else
            dirListing[file] = ""
          end
          fileNb = fileNb + 1
        end
      end
      return dirListing
    end
    
    --dofile[[../Lua/DumpObject.lua]] -- My own dump routine
    local dirListing = ListDirectory(dirToList)
    --~ print("\n" .. DumpObject(dirListing))
    print("Found " .. fileNb .. " files")
    
    --~ os.exit()
    
    -- Constants to change to adjust aspect
    local initialOffsetX = 20
    local offsetY = 50
    local offsetIncrementX = 20
    local offsetIncrementY = 12
    local iconOffset = 10
    
    local width = 800 -- Still arbitrary
    local titleHeight = width/50
    local height = offsetIncrementY * (fileNb + 1) + titleHeight
    local outfile = "CairoDirTree." .. outputType
    
    local ctxSurface
    if outputType == 'svg' then
      ctxSurface = cairo.SvgSurface(outfile, width, height)
    else
      ctxSurface = cairo.ImageSurface(CAIRO.FORMAT_RGB24, width, height)
    end
    local ctx = cairo.Context(ctxSurface)
    
    -- Display a file name
    -- file is the file name to display
    -- offsetX is the indentation
    function DisplayFile(file, bIsDir, offsetX)
      if bIsDir then
        ctx:save()
        ctx:select_font_face("Sans", CAIRO.FONT_SLANT_NORMAL, CAIRO.FONT_WEIGHT_BOLD)
        ctx:set_source_rgb(0.5, 0.0, 0.7)
      end
    
      -- Display file name
      ctx:move_to(offsetX, offsetY)
      ctx:show_text(file)
    
      if bIsDir then
        ctx:new_sub_path() -- Position independent of latest move_to
        -- Draw arc with absolute coordinates
        ctx:arc(offsetX - iconOffset, offsetY - offsetIncrementY/3, offsetIncrementY/3, 0, TWO_PI)
        -- Violet disk
        ctx:set_source_rgb(0.7, 0.0, 0.7)
        ctx:fill()
        ctx:restore() -- Restore original settings
      end
    
      -- Increment line offset
      offsetY = offsetY + offsetIncrementY
    end
    
    -- Erase background (white)
    ctx:set_source_rgb(1.0, 1.0, 1.0)
    ctx:paint()
    
    --~ ctx:set_line_width(0.01)
    
    -- Draw in dark blue
    ctx:set_source_rgb(0.0, 0.0, 0.3)
    ctx:select_font_face("Sans", CAIRO.FONT_SLANT_NORMAL, CAIRO.FONT_WEIGHT_BOLD)
    ctx:set_font_size(titleHeight)
    ctx:move_to(5, titleHeight)
    -- Display title
    ctx:show_text("Directory tree of " .. dirToList)
    
    -- Select font for file names
    ctx:select_font_face("Sans", CAIRO.FONT_SLANT_NORMAL, CAIRO.FONT_WEIGHT_NORMAL)
    ctx:set_font_size(10)
    offsetY = titleHeight * 2
    
    -- Do the job
    function DisplayDirectory(dirToList, offsetX)
      for k, v in pairs(dirToList) do
    --~ print(k, v)
        if type(v) == "table" then
          -- Sub-directory
          DisplayFile(k, true, offsetX)
          DisplayDirectory(v, offsetX + offsetIncrementX)
        else
          DisplayFile(k, false, offsetX)
        end
      end
    end
    
    DisplayDirectory(dirListing, initialOffsetX)
    
    if outputType == 'svg' then
        cairo.show_page(ctx)
    else
      --cairo.surface_write_to_png(ctxSurface, outfile)
      ctxSurface:write_to_png(outfile)
    end
    
    ctx:destroy()
    ctxSurface:destroy()
    
    print("Found " .. fileNb .. " files")
    

    当然,您可以更改样式。我没有画连接线,我没有看到它是必要的。我以后可能会选择添加它们。

        5
  •  2
  •   PhiLho    17 年前

    使用Graphviz的建议很好:您可以生成点文件,它将完成测量字符串、布局等艰苦工作。此外,它还可以以多种格式输出图形,包括矢量格式。

    我在邮件列表中发现一个Perl程序正是这样做的,但我就是找不到它!我复制了示例点文件并对其进行了研究,因为我不太了解这种声明性语法,我想学习更多。

    问题:对于最新的Graphviz,我在原始图形和我(手工)编写的图形中都有错误(或者更确切地说,在生成最终图表时有警告)。一些搜索显示,此错误在旧版本中找到,在较新版本中消失。看起来它回来了。

    我仍然会给出这个文件,也许它可以作为某个人的起点,或者它已经足够满足您的需要(当然,您仍然需要生成它)。

    digraph tree
    {
      rankdir=LR;
    
      DirTree [label="Directory Tree" shape=box]
    
      a_Foo_txt [shape=point]
      f_Foo_txt [label="Foo.txt", shape=none]
      a_Foo_txt -> f_Foo_txt
    
      a_Foo_Bar_html [shape=point]
      f_Foo_Bar_html [label="Foo Bar.html", shape=none]
      a_Foo_Bar_html -> f_Foo_Bar_html
    
      a_Bar_png [shape=point]
      f_Bar_png [label="Bar.png", shape=none]
      a_Bar_png -> f_Bar_png
    
      a_Some_Dir [shape=point]
      d_Some_Dir [label="Some Dir", shape=ellipse]
      a_Some_Dir -> d_Some_Dir
    
      a_VBE_C_reg [shape=point]
      f_VBE_C_reg [label="VBE_C.reg", shape=none]
      a_VBE_C_reg -> f_VBE_C_reg
    
      a_P_Folder [shape=point]
      d_P_Folder [label="P Folder", shape=ellipse]
      a_P_Folder -> d_P_Folder
    
      a_Processing_20081117_7z [shape=point]
      f_Processing_20081117_7z [label="Processing-20081117.7z", shape=none]
      a_Processing_20081117_7z -> f_Processing_20081117_7z
    
      a_UsefulBits_lua [shape=point]
      f_UsefulBits_lua [label="UsefulBits.lua", shape=none]
      a_UsefulBits_lua -> f_UsefulBits_lua
    
      a_Graphviz [shape=point]
      d_Graphviz [label="Graphviz", shape=ellipse]
      a_Graphviz -> d_Graphviz
    
      a_Tree_dot [shape=point]
      f_Tree_dot [label="Tree.dot", shape=none]
      a_Tree_dot -> f_Tree_dot
    
      {
        rank=same;
        DirTree -> a_Foo_txt -> a_Foo_Bar_html -> a_Bar_png -> a_Some_Dir -> a_Graphviz [arrowhead=none]
      }
      {
        rank=same;
        d_Some_Dir -> a_VBE_C_reg -> a_P_Folder -> a_UsefulBits_lua [arrowhead=none]
      }
      {
        rank=same;
        d_P_Folder -> a_Processing_20081117_7z [arrowhead=none]
      }
      {
        rank=same;
        d_Graphviz -> a_Tree_dot [arrowhead=none]
      }
    }
    
    > dot -Tpng Tree.dot -o Tree.png
    Error: lost DirTree a_Foo_txt edge
    Error: lost a_Foo_txt a_Foo_Bar_html edge
    Error: lost a_Foo_Bar_html a_Bar_png edge
    Error: lost a_Bar_png a_Some_Dir edge
    Error: lost a_Some_Dir a_Graphviz edge
    Error: lost d_Some_Dir a_VBE_C_reg edge
    Error: lost a_VBE_C_reg a_P_Folder edge
    Error: lost a_P_Folder a_UsefulBits_lua edge
    Error: lost d_P_Folder a_Processing_20081117_7z edge
    Error: lost d_Graphviz a_Tree_dot edge
    

    我将尝试另一个方向,使用Cairo,它也能够导出多种格式。这是更多的工作(计算位置/偏移),但结构简单,不应该太难。