Sử dụng công cụ nào để vẽ sơ đồ cây tệp [đã đóng]


90

Cho một cây tệp - một thư mục với các thư mục trong đó, v.v., bạn sẽ viết tập lệnh như thế nào để tạo sơ đồ cây tệp dưới dạng tệp đồ họa mà tôi có thể nhúng vào tài liệu trình xử lý văn bản. Tôi thích tệp vectơ (SVG, EPS, EMF ...) hơn. Công cụ phải chạy trên Windows, nhưng tốt nhất là đa nền tảng. Công cụ này có thể là thương mại nhưng tốt nhất là miễn phí.

Cập nhật 2012-02-20. Câu hỏi liên quan đến một tiểu dự án tài liệu. Tôi đã phải giải thích nơi các tệp (cụ thể là tài nguyên và tệp cấu hình) cư trú. Tôi đã kết thúc với việc sử dụng lệnh cây dos. Cả hai màn hình tôi nhận được kết quả (cho các thư mục ngắn) VÀ cho các thư mục dài hơn, tôi đã chuyển hướng đến một tệp văn bản, sau đó tôi đã chỉnh sửa. Ví dụ: nếu một thư mục con chứa 20 tệp được đánh tương tự mà riêng lẻ không quan trọng đối với thời điểm tôi đang thực hiện, tôi chỉ để lại hai và thay thế phần còn lại bằng một ... dòng. Sau đó, tôi in tệp ra bảng điều khiển một lần nữa và màn hình chụp lấy nó. Trước khi chụp màn hình, tôi phải sửa đổi màu nền trước thành đen và màu nền thành trắng, để trông đẹp hơn và tiết kiệm mực trong tài liệu sẽ được in.

Rất ngạc nhiên là không có công cụ nào tốt hơn cho nó. Nếu có thời gian, tôi sẽ viết một Tiện ích mở rộng Visio hoặc có thể là một số dòng lệnh tạo SVG. SVG là HTML5 không đạt tiêu chuẩn, thậm chí sẽ cho phép đưa vào tài liệu trực tuyến một cách dễ dàng.

Cập nhật 2017-10-17. Tôi rất tiếc vì câu hỏi này đã bị xóa vì không thuộc về SO. Vì vậy, tôi đã nói lại nó. Tôi cần một tập lệnh - không phải một công cụ WYSIWYG. Vì vậy, bất kỳ ngôn ngữ kịch bản hoặc thư viện nào cũng được. Vì vậy, nó là một câu hỏi viết mã, và tôi tin rằng thuộc về SO.


10
Tại sao câu hỏi này bị đóng lại? Có các DSL lập trình để vẽ cây: ví dụ như các công cụ như graphviz có thể giải quyết điều này "theo chương trình".
Piotr Lesnicki

5
Tôi sẽ mở lại điều này (dự kiến) bởi vì nếu nó là một "cách đơn giản để tôi hiển thị những gì trên màn hình", anh ấy sẽ yêu cầu một trình chụp màn hình. Nếu anh ta muốn vẽ nó, nó có thể là tài liệu thiết kế hoặc bản trình bày, do đó anh ta sẽ lập trình vào một lúc nào đó.
paxdiablo 07-08

2
Đã đồng ý. Tôi đã từng cần loại chức năng tương tự này trước đây và đã phải làm giả nó với Visio. Cần nó cho tài liệu EU. Chắc chắn là mã liên quan.
Joseph Ferris

6
RẤT ngu ngốc, để kết thúc điều này là lạc đề. Tôi cũng đã thấy cần một cái gì đó .. VẬY rất thích kiểm duyệt.
Boltimuss

1
Tôi xin lỗi nếu câu hỏi của tôi lạc đề ở đây. Tôi hiểu lý do tại sao. Cảm ơn tất cả những người đã đi qua, nó rất hữu ích. Để làm rõ, tôi cần một sơ đồ để đưa vào tài liệu của cây dự án. Ảnh chụp màn hình không cắt nó vì toàn bộ cây dài hơn vừa với một màn hình.
Michael

Câu trả lời:


95

Sao chép và dán từ lệnh MS-DOS treecũng có thể hiệu quả với bạn. Ví dụ:

cây

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

cây / F

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

cây / A

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

cây / F / A

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

Cú pháp [ nguồn ]

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

drive:\path - Ổ đĩa và thư mục chứa đĩa để hiển thị cấu trúc thư mục, không liệt kê tệp.

/F - Bao gồm tất cả các tệp sống trong mọi thư mục.

/A- Thay thế các ký tự đồ họa được sử dụng để liên kết các dòng bằng các ký tự ext, thay vì các ký tự đồ họa. /ađược sử dụng với các trang mã không hỗ trợ các ký tự đồ họa và để gửi đầu ra đến các máy in không diễn giải đúng các ký tự đồ họa.


1
Ý tưởng hay, nhưng nếu có các tệp / thư mục có các chữ cái có dấu, chúng sẽ nằm trong bộ mã OEM, không phải bộ mã Ansi. Tất nhiên, có lẽ là một vấn đề đối với hầu hết người dùng (ít nhất là nói tiếng Anh). Tương tự đối với các ký tự bán đồ họa.
PhiLho 07-08

4
Linux cũng có một lệnh "cây" như thế này, tôi mới phát hiện ra sau khi xem qua câu hỏi Stack Overflow này. Cảm ơn vì đã chỉ ra cái tên mà tôi nên tìm kiếm! "tree -A" là cách tạo cây bằng cách sử dụng các ký tự vẽ đẹp; đơn giản "cây" chỉ giới hạn chính nó trong ASCII.
Brandon Rhodes

1
tốt đẹp, tôi thậm chí không biết lệnh này
MiniScalope

Nhiều lựa chọn tồn tại, cảm ơn tất cả vì đã đưa chúng lên. Tôi coi câu trả lời này là một câu trả lời, bởi vì cuối cùng thì đó là những gì tôi đã sử dụng.
Michael

1
Hoặc lưu nó thẳng vào một tệp: tree > file_structure.txtTôi biết điều này hoạt động trên hệ thống Unix. Tôi không biết liệu nó có hoạt động trên Windows hay không.
Lucio Mollinedo

19

Graphviz - từ trang web:

Các chương trình bố cục Graphviz lấy mô tả đồ thị bằng ngôn ngữ văn bản đơn giản và tạo sơ đồ ở một số định dạng hữu ích như hình ảnh và SVG cho các trang web, Postscript để đưa vào PDF hoặc các tài liệu khác; hoặc hiển thị trong trình duyệt đồ thị tương tác. (Graphviz cũng hỗ trợ GXL, một phương ngữ XML.)

Đó là công cụ đơn giản và hiệu quả nhất mà tôi đã tìm thấy để tạo ra nhiều loại biểu đồ dạng hộp và đường. Tôi có và sử dụng Visio và OmniGraffle, nhưng luôn có sự cám dỗ để thực hiện "chỉ một lần điều chỉnh nữa".

Cũng khá dễ dàng để viết mã để tạo ra định dạng "tệp chấm" mà Graphiz sử dụng, vì vậy việc tạo sơ đồ tự động cũng nằm trong tầm tay.


5

Như đã hứa, đây là phiên bản Cairo của tôi. Tôi viết kịch bản nó bằng Lua, sử dụng lfs để xem các thư mục. Tôi thích những thử thách nhỏ này, vì chúng cho phép tôi khám phá các API mà tôi muốn đào từ lâu ...
lfs và LuaCairo đều là nền tảng đa nền tảng, vì vậy nó sẽ hoạt động trên các hệ thống khác (được thử nghiệm trên WinXP Pro SP3 của Pháp).

Tôi đã tạo tên tệp bản vẽ phiên bản đầu tiên khi tôi đi bộ trên cây. Ưu điểm: không cần bộ nhớ. Không thuận tiện: Tôi phải chỉ định kích thước hình ảnh trước, vì vậy danh sách có thể bị cắt bỏ.

Vì vậy, tôi đã tạo phiên bản này, đầu tiên đi bộ cây thư mục, lưu trữ nó trong một bảng Lua. Sau đó, biết số lượng tệp, tạo canvas cho phù hợp (ít nhất là theo chiều dọc) và vẽ tên.
Bạn có thể dễ dàng chuyển đổi giữa kết xuất PNG và SVG. Vấn đề với cái sau: Cairo tạo nó ở mức thấp, vẽ các chữ cái thay vì sử dụng khả năng văn bản của SVG. Ít nhất, nó đảm bảo kết xuất chính xác ngay cả trên các hệ thống không có phông chữ. Nhưng các tệp lớn hơn ... Không thực sự là vấn đề nếu bạn nén nó sau đó, để có tệp .svgz.
Hoặc không quá khó để tạo SVG trực tiếp, trước đây tôi đã sử dụng Lua để tạo 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")

Tất nhiên, bạn có thể thay đổi phong cách. Tôi đã không vẽ các đường kết nối, tôi thấy nó không cần thiết. Tôi có thể thêm chúng vào tùy ý sau.


3

Tại sao bạn không thể chỉ tạo cấu trúc tệp trên hệ thống tệp Windows và điền vào nó những tên bạn muốn, sau đó sử dụng trình chụp ảnh màn hình như HyperSnap (hoặc Alt-PrtScr phổ biến) để chụp một phần của cửa sổ Explorer.

Tôi đã làm điều này khi 'demo' một ứng dụng internet có các phần có thể thu gọn, tôi chỉ cần tạo các tệp trông giống như các mục nhập mong muốn của tôi.

HyperSnap cung cấp ít nhất JPG (có thể là những thứ khác nhưng tôi chưa bao giờ bận tâm đến việc điều tra).

Hoặc bạn có thể chụp màn hình các biểu tượng +/- từ Explorer và sử dụng chúng trong chính MS Word Draw để tạo ảnh của bạn, nhưng tôi chưa bao giờ có thể khiến MS Word Draw tự hoạt động đúng.


2

Lời khuyên để sử dụng Graphviz là tốt: bạn có thể tạo tệp chấm và nó sẽ thực hiện công việc khó khăn của việc đo chuỗi, thực hiện bố cục, v.v. Thêm vào đó, nó có thể xuất biểu đồ ở nhiều định dạng, bao gồm cả các định dạng vectơ.

Tôi đã tìm thấy một chương trình Perl làm chính xác điều đó, trong một danh sách gửi thư, nhưng tôi không thể tìm thấy nó trở lại! Tôi đã sao chép tệp chấm mẫu và nghiên cứu nó, vì tôi không biết nhiều về cú pháp khai báo này và tôi muốn tìm hiểu thêm một chút.

Vấn đề: với Graphviz mới nhất, tôi có lỗi (hay đúng hơn là cảnh báo, khi sơ đồ cuối cùng được tạo), cả trong biểu đồ gốc và biểu đồ tôi đã viết (bằng tay). Một số tìm kiếm cho thấy lỗi này đã được tìm thấy trong các phiên bản cũ và biến mất trong các phiên bản gần đây hơn. Có vẻ như nó đã trở lại.

Tôi vẫn cung cấp tệp, có thể nó có thể là điểm khởi đầu cho ai đó, hoặc có thể là đủ cho nhu cầu của bạn (tất nhiên, bạn vẫn phải tạo nó).

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

Tôi sẽ thử một hướng khác, sử dụng Cairo, cũng có thể xuất một số định dạng. Nó là công việc nhiều hơn (các vị trí tính toán / hiệu số) nhưng cấu trúc đơn giản, không nên quá khó.


1
Steve DeRose có cấu trúc tệp tạo Perlscript -> tệp chấm tại derose.net/steve/utilities
claj
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.