developer tip

파일 트리 다이어그램을 그리는 데 사용할 도구

optionbox 2020. 10. 17. 10:25
반응형

파일 트리 다이어그램을 그리는 데 사용할 도구


파일 트리 (디렉토리가있는 디렉토리 등)가 주어지면 파일 트리 다이어그램을 워드 프로세서 문서에 포함 할 수있는 그래픽 파일로 만드는 스크립트를 어떻게 작성 하시겠습니까? 벡터 (SVG, EPS, EMF ...) 파일을 선호합니다. 이 도구는 Windows에서 실행되어야하지만 가급적 크로스 플랫폼에서 실행되어야합니다. 이 도구는 상업적 일 수 있지만 바람직하게는 무료입니다.

2012-02-20 업데이트. 질문은 문서 하위 프로젝트와 관련이 있습니다. 파일 (특히 리소스 및 구성 파일)이있는 위치를 설명해야했습니다. 나는 도스 트리 명령을 사용하여 끝났습니다. 두 화면 모두 결과 (짧은 폴더)를 가져 왔고 긴 폴더의 경우 텍스트 파일로 리디렉션 한 다음 편집했습니다. 예를 들어 하위 폴더에 내가 만드는 시점에 개별적으로 중요하지 않은 유사한 형식의 파일 20 개가 포함 된 경우 두 개만 남겨두고 나머지는 ... 줄로 바꿨습니다. 그런 다음 파일을 다시 콘솔에 인쇄하고 화면을 잡았습니다. 화면을 잡기 전에 전경색을 검은 색으로, 배경색을 흰색으로 수정하여 인쇄 할 문서의 잉크를 더 잘 보이고 절약해야했습니다.

더 나은 도구가 없다는 것은 매우 놀랍습니다. 시간이 있다면 Visio Extension을 작성하거나 SVG를 생성하는 명령 줄이 될 수 있습니다. SVG는 HTML5 이하 표준이므로 온라인 문서에 쉽게 포함시킬 수 있습니다.

2017-10-17 업데이트. 이 질문이 SO에 속하지 않는 것으로 제거되어 유감입니다. 그래서 나는 그것을 다시 표현했습니다. WYSIWYG 도구가 아닌 스크립트가 필요합니다. 따라서 모든 스크립팅 언어 또는 라이브러리는 괜찮습니다. 그래서 그것은 코드 작성 질문이며 나는 SO에 속한다고 믿습니다.


MS-DOS tree명령 에서 복사 및 붙여 넣기도 사용할 수 있습니다. 예 :

나무

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

나무 / F

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

나무 / A

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 ]

tree[ drive:] [ path] [ /F] [ /A]

drive:\path — 파일을 나열하지 않고 디렉토리 구조를 표시하기위한 디스크가 포함 된 드라이브 및 디렉토리.

/F — 모든 디렉토리에있는 모든 파일을 포함합니다.

/A— 라인을 연결하는 데 사용되는 그래픽 문자를 그래픽 문자 대신 ext 문자로 대체합니다. /a그래픽 문자를 지원하지 않는 코드 페이지와 그래픽 문자를 제대로 해석하지 않는 프린터로 출력을 보내는 데 사용됩니다.


Graphviz- 웹 페이지에서 :

Graphviz 레이아웃 프로그램은 간단한 텍스트 언어로 그래프를 설명하고 웹 페이지 용 이미지 및 SVG, PDF 또는 기타 문서에 포함 할 Postscript와 같은 여러 유용한 형식으로 다이어그램을 만듭니다. 또는 대화 형 그래프 브라우저에 표시합니다. (Graphviz는 XML 방언 인 GXL도 지원합니다.)

다양한 상자 및 선 다이어그램을 만드는 데 사용 된 가장 간단하고 생산적인 도구입니다. Visio와 OmniGraffle을 가지고 있고 사용하고 있지만 항상 "한 번만 더 조정"하고 싶은 유혹이 있습니다.

또한 Graphiz가 사용하는 "도트 파일"형식을 생성하는 코드를 작성하는 것도 매우 쉬우므로 자동화 된 다이어그램 생성도 매우 편리합니다.


약속대로 여기 내 카이로 버전이 있습니다. lfs를 사용하여 디렉토리를 탐색하는 Lua로 스크립트를 작성했습니다. 저는이 작은 도전이 마음에
듭니다 . 꽤 오랫동안 발굴하고 싶었던 API를 탐색 할 수 있기 때문입니다. lfs와 LuaCairo는 모두 크로스 플랫폼이므로 다른 시스템에서도 작동해야합니다 (프랑스 WinXP Pro SP3에서 테스트 됨).

나무를 걸으며 첫 번째 버전의 도면 파일 이름을 만들었습니다. 장점 : 메모리 오버 헤드가 없습니다. 불편 : 사전에 이미지 크기를 지정해야하므로 목록이 잘릴 수 있습니다.

그래서 저는이 버전을 만들었습니다. 먼저 디렉토리 트리를 살펴보고 Lua 테이블에 저장했습니다. 그런 다음 파일 수를 알고 캔버스에 맞게 (적어도 수직으로) 만들고 이름을 그립니다.
PNG 렌더링과 SVG 렌더링간에 쉽게 전환 할 수 있습니다. 후자의 문제 : Cairo는 SVG의 텍스트 기능을 사용하는 대신 문자를 그리는 낮은 수준에서 생성합니다. 글쎄, 적어도 글꼴이없는 시스템에서도 정확한 렌딩을 보장합니다. 하지만 파일은 더 큽니다. .svgz 파일을 가지기 위해 압축 한 후에는 문제가되지 않습니다.
또는 SVG를 직접 생성하는 것이 너무 어렵지 않아야합니다. 예전에 Lua를 사용하여 SVG를 생성했습니다.

-- 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")

물론 스타일을 변경할 수 있습니다. 나는 연결선을 그리지 않았고 필요에 따라 보지 못했습니다. 나중에 선택적으로 추가 할 수 있습니다.


Why could you not just make a file structure on the Windows file system and populate it with your desired names, then use a screen grabber like HyperSnap (or the ubiquitous Alt-PrtScr) to capture a section of the Explorer window.

I did this when 'demoing' an internet application which would have collapsible sections, I just had to create files that looked like my desired entries.

HyperSnap gives JPGs at least (probably others but I've never bothered to investigate).

Or you could screen capture the icons +/- from Explorer and use them within MS Word Draw itself to do your picture, but I've never been able to get MS Word Draw to behave itself properly.


The advice to use Graphviz is good: you can generate the dot file and it will do the hard work of measuring strings, doing the layout, etc. Plus it can output the graphs in lot of formats, including vector ones.

I found a Perl program doing precisely that, in a mailing list, but I just can't find it back! I copied the sample dot file and studied it, since I don't know much of this declarative syntax and I wanted to learn a bit more.

Problem: with latest Graphviz, I have errors (or rather, warnings, as the final diagram is generated), both in the original graph and the one I wrote (by hand). Some searches shown this error was found in old versions and disappeared in more recent versions. Looks like it is back.

I still give the file, maybe it can be a starting point for somebody, or maybe it is enough for your needs (of course, you still have to generate it).

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

I will try another direction, using Cairo, which is also able to export a number of formats. It is more work (computing positions/offsets) but the structure is simple, shouldn't be too hard.

참고URL : https://stackoverflow.com/questions/347551/what-tool-to-use-to-draw-file-tree-diagram

반응형