Jakiego narzędzia użyć do rysowania diagramu drzewa plików [zamknięte]

90

Biorąc pod uwagę drzewo plików - katalog z katalogami w nim itp., W jaki sposób napisałbyś skrypt tworzący diagram drzewa plików jako plik graficzny, który mogę osadzić w dokumencie edytora tekstu. Wolę pliki wektorowe (SVG, EPS, EMF ...). Narzędzie musi działać w systemie Windows, ale najlepiej na wielu platformach. Narzędzie może być komercyjne, ale najlepiej bezpłatne.

Aktualizacja 2012-02-20. Pytanie dotyczyło podprojektu dokumentacji. Musiałem wyjaśnić, gdzie znajdują się pliki (w szczególności zasoby i pliki konfiguracyjne). Skończyło się na użyciu polecenia dos tree. Obaj ekran złapał wynik (dla krótkich folderów) ORAZ dla dłuższych folderów przekierowałem do pliku tekstowego, który następnie edytowałem. Na przykład, jeśli podfolder zawierał 20 podobnie wpisanych plików, które z osobna nie były ważne w momencie, w którym robiłem, zostawiłem tylko dwa, a resztę zastąpiłem jedną ... linią. Następnie ponownie wydrukowałem plik na konsoli i screen go złapał. Przed robieniem zrzutów ekranu musiałem zmienić kolor pierwszego planu na czarny, a kolor tła na biały, aby wyglądać lepiej i oszczędzać atrament w dokumencie, który miał zostać wydrukowany.

Zaskakujące jest to, że nie ma do tego lepszego narzędzia. Gdybym miał czas, napisałbym rozszerzenie Visio lub może to być wiersz poleceń, który tworzy SVG. SVG, który nie spełnia standardów HTML5, umożliwiłby nawet bezbolesne włączenie do dokumentacji online.

Aktualizacja 2017-10-17. Przykro mi, że to pytanie zostało usunięte jako nienależące do SO. Więc przeredagowałem to. Potrzebuję skryptu - nie narzędzia WYSIWYG. Więc każdy język skryptowy lub biblioteka jest w porządku. Jest to więc pytanie dotyczące pisania kodu i uważam, że należy do SO.

Michał
źródło
10
Dlaczego to pytanie jest zamknięte? Istnieją programy DSL do rysowania drzew: np. Narzędzia takie jak graphviz, które mogą rozwiązać ten problem „programowo”.
Piotr Lesnicki
5
Zamierzam ponownie to otworzyć (wstępnie), ponieważ gdyby było to proste „jak pokazać, co jest na ekranie”, poprosiłby o narzędzie do przechwytywania ekranu. Jeśli chce to narysować, prawdopodobnie jest to dokument projektowy lub prezentacja, dlatego w pewnym momencie będzie programował.
paxdiablo
2
Zgoda. Wcześniej potrzebowałem tego samego typu funkcji i uciekłem się do udawania jej w programie Visio. Potrzebowałem go do dokumentacji UE. Zdecydowanie był związany z kodem.
Joseph Ferris,
6
BARDZO głupie, aby zamknąć to jako nie na temat. Ja też potrzebowałem czegoś .. WIĘC uwielbia cenzurować.
Boltimuss,
1
Przepraszam, jeśli moje pytanie jest tutaj nie na temat. Rozumiem, dlaczego. Dzięki wszystkim, którzy odpowiedzieli, było to pomocne. Aby to wyjaśnić, potrzebowałem diagramu do dołączenia do dokumentacji drzewa projektu. Zrzut ekranu go nie wycina, ponieważ całe drzewo jest dłuższe niż mieści się na jednym ekranie.
Michael,

Odpowiedzi:

95

Kopiowanie i wklejanie z polecenia MS-DOS treemoże również zadziałać. Przykłady:

drzewo

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

drzewo / F

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

drzewo / A

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

drzewo / F / A

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

Składnia [ źródło ]

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

drive:\path - Dysk i katalog zawierający dysk do wyświetlania struktury katalogów, bez listy plików.

/F - Uwzględnij wszystkie pliki znajdujące się w każdym katalogu.

/A- Zastąp znaki graficzne używane do łączenia wierszy znakami rozszerzającymi zamiast znaków graficznych. /ajest używany w przypadku stron kodowych, które nie obsługują znaków graficznych i do wysyłania danych wyjściowych do drukarek, które nie interpretują poprawnie znaków graficznych.

svinto
źródło
1
Dobry pomysł, ale jeśli są pliki / foldery z akcentowanymi literami, będą one zapisane w zestawie znaków OEM, a nie Ansi. Prawdopodobnie nie jest to problem dla większości użytkowników (przynajmniej mówiących po angielsku), oczywiście. To samo dotyczy znaków półgraficznych.
PhiLho
4
Linux ma również takie polecenie "drzewo", które właśnie odkryłem po sprawdzeniu tego pytania przepełnienia stosu. Dziękuję za wskazanie nazwiska, którego powinienem szukać! "drzewo -A" to sposób tworzenia drzewa przy użyciu ładnych rysunków; zwykłe „drzewo” ogranicza się tylko do ASCII.
Brandon Rhodes
1
fajnie, nawet nie znałem tego polecenia
MiniScalope
Istnieje wiele opcji, dzięki wszystkim za ich wychowanie. Uważam to za odpowiedź, ponieważ to właśnie wykorzystałem w końcu.
Michael,
1
Lub zapisz go bezpośrednio do pliku: tree > file_structure.txtwiem, że to działa w systemach Unix. Nie wiem, czy działa również w systemie Windows.
Lucio Mollinedo
19

Graphviz - ze strony internetowej:

Programy graficzne Graphviz pobierają opisy wykresów w prostym języku tekstowym i tworzą diagramy w kilku przydatnych formatach, takich jak obrazy i SVG dla stron internetowych, Postscript do dołączenia do PDF lub innych dokumentów; lub wyświetlić w interaktywnej przeglądarce wykresów. (Graphviz obsługuje również GXL, dialekt XML).

To najprostsze i najbardziej produktywne narzędzie, jakie znalazłem, do tworzenia różnych diagramów ramek i linii. Mam i używam Visio i OmniGraffle, ale zawsze istnieje pokusa, aby dokonać „jeszcze jednej korekty”.

Bardzo łatwo jest również napisać kod w celu utworzenia formatu „pliku z kropkami”, który wykorzystuje Graphiz, więc zautomatyzowane tworzenie diagramów jest również łatwo dostępne.

joel.neely
źródło
5

Zgodnie z obietnicą, oto moja wersja z Kairu. Napisałem go z Luą, używając lfs do poruszania się po katalogach. Uwielbiam te małe wyzwania, ponieważ pozwalają mi odkrywać interfejsy API, które chciałem kopać od dłuższego czasu ...
lfs i LuaCairo są międzyplatformowe, więc powinno działać na innych systemach (testowane na francuskim WinXP Pro SP3).

Stworzyłem nazwy plików rysunków pierwszej wersji, gdy chodziłem po drzewie. Zaleta: brak narzutu pamięci. Niedogodność: muszę wcześniej określić rozmiar obrazu, więc aukcje prawdopodobnie zostaną obcięte.

Zrobiłem więc tę wersję, najpierw chodząc po drzewie katalogów, przechowując ją w tabeli Lua. Następnie, znając liczbę plików, tworząc kanwę do dopasowania (przynajmniej w pionie) i rysując nazwy.
Możesz łatwo przełączać się między renderowaniem PNG i SVG. Problem z tym drugim: Cairo generuje go na niskim poziomie, rysując litery zamiast korzystać z możliwości tekstowych SVG. Przynajmniej gwarantuje dokładne renderowanie nawet w systemach bez czcionki. Ale pliki są większe ... Nie ma problemu, jeśli skompresujesz je później, aby mieć plik .svgz.
Lub nie powinno być zbyt trudne bezpośrednie wygenerowanie SVG, w przeszłości używałem Lua do generowania 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")

Oczywiście możesz zmienić style. Nie narysowałem linii połączeń, nie uznałem tego za konieczne. Mogę dodać je później.

PhiLho
źródło
3

Dlaczego nie mógłbyś po prostu utworzyć struktury plików w systemie plików Windows i wypełnić go żądanymi nazwami, a następnie użyć narzędzia do przechwytywania ekranu, takiego jak HyperSnap (lub wszechobecny Alt-PrtScr), aby przechwycić sekcję okna Eksploratora.

Zrobiłem to podczas „demonstrowania” aplikacji internetowej, która miałaby składane sekcje, po prostu musiałem utworzyć pliki, które wyglądałyby jak moje pożądane wpisy.

HyperSnap daje przynajmniej JPG (prawdopodobnie inne, ale nigdy nie zadałem sobie trudu, aby to zbadać).

Możesz też przechwycić ikony +/- z Eksploratora i użyć ich w samym programie MS Word Draw, aby zrobić swoje zdjęcie, ale nigdy nie udało mi się sprawić, aby MS Word Draw zachowywał się poprawnie.

paxdiablo
źródło
2

Porada dotycząca korzystania z Graphviz jest dobra: możesz wygenerować plik z kropką i wykona on ciężką pracę polegającą na mierzeniu ciągów, tworzeniu układu itp. Ponadto może wyświetlać wykresy w wielu formatach, w tym wektorowych.

Znalazłem program w Perlu, który robi dokładnie to, na liście mailingowej, ale po prostu nie mogę go znaleźć! Skopiowałem przykładowy plik z kropką i przestudiowałem go, ponieważ nie znam zbyt wiele tej deklaratywnej składni i chciałem dowiedzieć się więcej.

Problem: z najnowszym Graphvizem mam błędy (a raczej ostrzeżenia, jak generowany jest ostateczny diagram), zarówno w oryginalnym wykresie, jak i tym, który napisałem (ręcznie). Niektóre wyszukiwania pokazały, że ten błąd został znaleziony w starszych wersjach i zniknął w nowszych wersjach. Wygląda na to, że wrócił.

Plik nadal daję, może to może być dla kogoś punkt wyjścia, a może wystarczy do Twoich potrzeb (oczywiście nadal musisz go wygenerować).

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

Spróbuję w innym kierunku, używając Cairo, który jest również w stanie eksportować wiele formatów. To więcej pracy (obliczanie pozycji / przesunięć), ale struktura jest prosta, nie powinna być zbyt trudna.

PhiLho
źródło
1
Steve DeRose ma strukturę plików w Perlscript
claj