Какой инструмент использовать для построения диаграммы дерева файлов [закрыто]

92

Учитывая файловое дерево - каталог с каталогами в нем и т.д., как бы вы написали сценарий для создания диаграммы файлового дерева в виде графического файла, который я могу встроить в документ текстового процессора. Я предпочитаю векторные (SVG, EPS, EMF ...) файлы. Инструмент должен работать в Windows, но желательно кроссплатформенный. Инструмент может быть коммерческим, но предпочтительно бесплатным.

Обновление 2012-02-20. Вопрос касался подпроекта документации. Пришлось объяснять, где находятся файлы (в частности, ресурсы и файлы конфигурации). В итоге я использовал команду дерева досок. Я как экран захватил результат (для коротких папок), так и для более длинных папок я перенаправил в текстовый файл, который затем отредактировал. Например, если подпапка содержала 20 файлов с одинаковым типом, которые по отдельности не были важны для того, о чем я говорил, я оставил только два, а остальные заменил одной строкой ... Затем я снова распечатал файл на консоль, и экран захватил его. Перед захватом экрана мне пришлось изменить цвет переднего плана на черный, а цвет фона на белый, чтобы лучше выглядеть и сэкономить чернила в документе, который будет напечатан.

Очень удивительно, что для этого нет лучшего инструмента. Если бы у меня было время, я бы написал расширение Visio или, возможно, какую-нибудь командную строку, которая создает SVG. SVG не соответствует стандартам HTML5, поэтому его можно было бы безболезненно включить в онлайн-документацию.

Обновление 2017-10-17. Мне очень жаль, что этот вопрос был удален как не принадлежащий SO. Поэтому я изменил его формулировку. Мне нужен скрипт, а не инструмент WYSIWYG. Так что любой язык сценариев или библиотека подойдут. Так что это вопрос написания кода, и я считаю, что он принадлежит SO.

Майкл
источник
10
Почему этот вопрос закрыт? Существуют программные DSL для рисования деревьев: например, такие инструменты, как graphviz, которые могут решить эту проблему «программно».
Петр Лесницки
5
Я собираюсь снова открыть это (предварительно), потому что если бы это было простое «как мне показать, что на экране», он бы попросил захватить экран. Если он захочет нарисовать его, то, вероятно, для дизайн-документации или презентации, следовательно, в какой-то момент он будет программировать.
paxdiablo
2
Согласовано. Мне раньше требовалась такая же функциональность, и я прибегал к подделке с помощью Visio. Это необходимо для документации ЕС. Определенно было связано с кодом.
Джозеф Феррис,
6
ОЧЕНЬ глупо закрывать это как не по теме. Я тоже в чем-то нуждался .. ТАК любит цензуру.
Boltimuss
1
Прошу прощения, если мой вопрос здесь не по теме. Я понимаю причину. Спасибо всем, кто ответил, это было полезно. Для пояснения мне потребовалась диаграмма, которую нужно включить в документацию дерева проекта. Скриншот не режет, потому что все дерево длиннее, чем умещается на одном экране.
Майкл

Ответы:

98

Копирование и вставка из команды 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
...

дерево / А

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
...

Синтаксис [ источник ]

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

drive:\path - Диск и каталог, содержащий диск, для отображения структуры каталогов без перечисления файлов.

/F - Включите все файлы, находящиеся в каждом каталоге.

/A- Замените графические символы, используемые для связывания строк, на символы ext вместо графических символов. /aиспользуется с кодовыми страницами, которые не поддерживают графические символы, и для отправки вывода на принтеры, которые неправильно интерпретируют графические символы.

Свинто
источник
1
Хорошая идея, но если есть файлы / папки с диакритическими буквами, они будут в кодировке OEM, а не в кодировке Ansi. Наверное, это не проблема для большинства (по крайней мере, англоговорящих) пользователей, конечно. То же самое для полуграфических символов.
PhiLho
4
В Linux также есть такая команда «tree», которую я только что обнаружил после проверки этого вопроса о переполнении стека. Спасибо, что указали имя, которое я должен искать! «tree -A» - это как создать дерево, используя симпатичные рисованные символы; простое «дерево» просто ограничивается ASCII.
Брэндон Родс,
1
хорошо, я даже не знал эту команду
MiniScalope
Есть много вариантов, спасибо всем за то, что подняли их. Я считаю это ответом, потому что в итоге я использовал именно его.
Майкл
1
Или сохраните его прямо в файл: tree > file_structure.txtя знаю, что это работает в системах Unix. Я не знаю, работает ли он и в Windows.
Лучио Моллинедо,
19

Graphviz - с веб-страницы:

Программы компоновки Graphviz берут описания графиков на простом текстовом языке и создают диаграммы в нескольких полезных форматах, таких как изображения и SVG для веб-страниц, Postscript для включения в PDF или другие документы; или отобразить в браузере интерактивных графиков. (Graphviz также поддерживает GXL, диалект XML.)

Это самый простой и наиболее производительный инструмент, который я нашел для создания множества диаграмм в виде прямоугольников и линий. У меня есть и использую Visio и OmniGraffle, но всегда есть соблазн сделать «еще одну корректировку».

Также довольно легко написать код для создания формата «точечного файла», который использует Graphiz, поэтому автоматическое создание диаграмм также находится в пределах досягаемости.

Joel.neely
источник
5

Как и обещал, вот моя Каирская версия. Я написал его с помощью Lua, используя lfs для просмотра каталогов. Мне нравятся эти небольшие проблемы, поскольку они позволяют мне исследовать 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")

Конечно, вы можете изменить стили. Линии соединения не рисовал, не видел как надо. При желании я могу добавить их позже.

PhiLho
источник
3

Почему бы вам не просто создать файловую структуру в файловой системе Windows и заполнить ее желаемыми именами, а затем использовать средство захвата экрана, такое как HyperSnap (или вездесущий Alt-PrtScr), чтобы захватить часть окна проводника.

Я сделал это, когда «демонстрировал» интернет-приложение, в котором были бы сворачиваемые разделы, мне просто нужно было создать файлы, которые выглядели бы как мои желаемые записи.

HyperSnap предоставляет по крайней мере JPG (возможно, другие, но я никогда не утруждал себя исследованием).

Или вы можете сделать снимок экрана с иконками +/- из проводника и использовать их в самом MS Word Draw, чтобы сделать ваше изображение, но мне никогда не удавалось заставить MS Word Draw вести себя должным образом.

Paxdiablo
источник
2

Совет по использованию 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, который также может экспортировать ряд форматов. Это больше работы (вычисление позиций / смещений), но структура проста и не должна быть слишком сложной.

PhiLho
источник
1
У Стива ДеРоуза есть Perlscript, создающий файловую структуру -> точечный файл на derose.net/steve/utilities
claj