Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как древовидно визуализировать ArrayOfRecord в VT 
:(
    Опции темы
Sheleh
Дата 21.4.2011, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 21.4.2011

Репутация: нет
Всего: нет



Здравствуйте, помогите пожалуйста визуализировать линейную структуру Objects: array of Tobjects;: 

Код

  Tobjects = record
    ID, ParentID, Name, Num, Time: string;
    items: array[1..16] of string;


В этой структуре иерархия объектов задается полями ID (собственный индекс) и ParentID (индекс родителя, которому принадлежит объект). Например:
Код

ID;ParentID;Name;Num;Time
1;0;Radius;R001;40648.1033536806
2;1;Tr;0116;40648.5782788079
3;1;Tr;0000;40648.5796839699
4;3;Dev;C;40648.5796839699
5;3;Dev;1;40648.5764067014
6;5;Sh;1;40648.5733965394
7;1;Tr;0091;40648.5737310995


На данный момент я заполняю VT по примеру обычным списком без иерархии
Код

Процедура заполнения;
var
  NewNode: PVirtualNode;
  NewObject: Pobjects;
begin
     for i:=0 to ObjectsCount do
      begin
         NewNode := VT.AddChild(VT.FocusedNode);
         NewObject := VT.GetNodeData(NewNode);
         NewObject^:=Objects[index];
      end;
end;

//Процедура отображения
procedure TMainForm.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  ObjectNode: PObjects;
begin
  ObjectNode := VT.GetNodeData(Node);
  if Assigned(ObjectNode) then
    case Column of
      0: CellText := ObjectNode^.ID;
      1: CellText := ObjectNode^.ParentID;
      2: CellText := ObjectNode^.Name;
      3: CellText := ObjectNode^.Num;
      4: CellText := ObjectNode^.Time;
    end;
end;


А как при заполнении зная индекс родителя ParentID сфокусировать родительский node по ID, что бы вставить от него Child Node. Надеюсь я ясно выразился ) 

За ранее спасибо!
PM MAIL   Вверх
cat512
Дата 21.4.2011, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 438
Регистрация: 20.3.2007

Репутация: 7
Всего: 15



Пожалуйста, заранее.
Цитата

сфокусировать родительский node по ID

Цитата

Надеюсь я ясно выразился 

Абсолютно не ясно.  smile  Ты фотографией увлекаешься?
PM MAIL   Вверх
Sheleh
Дата 22.4.2011, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 21.4.2011

Репутация: нет
Всего: нет



Цитата
Абсолютно не ясно.  Ты фотографией увлекаешься?
 нет, я садовод  smile Я не про оптический фокус, а про VT.AddChild(VT.FocusedNode)

Ладно, попробую еще раз по порядку. 

Есть массив записей - Objects: array of Tobjects;
Запись содержит текстовые поля: Tobjects = record
ID, ParentID, Name, Num, Time: string; с примерно следующим содержанием:
1;0;Radius;R001;40648.1033536806
2;1;Tr;0116;40648.5782788079
3;1;Tr;0000;40648.5796839699
4;3;Dev;C;40648.5796839699
5;3;Dev;1;40648.5764067014
6;5;Sh;1;40648.5733965394
7;1;Tr;0091;40648.5737310995

Казалось бы простой масиив строк, но здесь есть ирархия. Каждая запись имеет собственный ID и ParentID - это ID родителя, к которому она относится. Для наглядности вот те же самые данные в древовидной форме.
Код

0 - root
        |-----1;0;Radius;R001;40648.1033536806
                |
                |-----2;1;Tr;0116;40648.5782788079
                |
                |-----3;1;Tr;0000;40648.5796839699
                |       |
                |       |----4;3;Dev;C;40648.5796839699
                |       |
                |       |----5;3;Dev;1;40648.5764067014
                |              |
                |              |------6;5;Sh;1;40648.5733965394
                |
                |-----7;1;Tr;0091;40648.5737310995



как это можно древовидно отобразить в VT?
PM MAIL   Вверх
MetalFan
Дата 22.4.2011, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Предлагаю сделать парсер с загрузкой данных в объектную структуру, а затем уже сделать отображение структуры в VT - как два байта переслать.
Хотя конечно можно и сразу в VT грузить.
Примерный алгоритм:
1. Читаем запись, разбираем поля, смотрим ParentID, 
2. ищем нод в дереве с ID=ParentID
3. Если нашли, то добавляем ему ребенка с данными из п.1
4. Если не нашли, то или пропускаем, или добавляем в корень.
Но лучше сделать загрузку объектной модели, которую затем отражать в VT используя все его прелести с OnInitNode/OnInitChildNodes


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Sheleh
Дата 23.4.2011, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 21.4.2011

Репутация: нет
Всего: нет



MetalFan, я в этом новичок, в какую именно объектную структуру (TObjects?) можно это загрузить, и какие это даст плюсы, кроме простоты отображения в VT.

Плюс моей структуры, как мне кажется, это простота доступа к каждому объекту по его ID в независимости в корне объект, или глубокой вложенности, безо всяких рекурсивных поисков. Да и вложенность в моем случае нужна больше для наглядности при отображении, в программе же это должно выглядеть как список объектов. 
Цитата

2. ищем нод в дереве с ID=ParentID
3. Если нашли, то добавляем ему ребенка с данными из п.1
В общем по такому алгоритму я и хотел работать, но вопрос не в алгоритме, а в его реализации. Просто не могу понять, если данные напрямую в VT не содержатся, а связаны с массивом записей только поинтерами, то как по ним выйти на нод, которому нужно добавить ребенка? Или другими словами:
2. ищем нод в дереве с ID=ParentID - а в дереве ли мы ищем? Как искать в дереве VT, если в нем только поинтеры, там же нет ID?


Перекурил всю статью, но так и не нашел, где в VT хранятся ноды, и как к ним обращаться по индексу.

Это сообщение отредактировал(а) Sheleh - 23.4.2011, 21:16
PM MAIL   Вверх
cat512
Дата 24.4.2011, 03:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 438
Регистрация: 20.3.2007

Репутация: 7
Всего: 15



Эта задача формулируется просто - "Загрузить древовидную структуру данных в Тривью".
Реализуется она с помощью алгоритма динамически расширяемого дерева. Строится рекур. функия типа
Код

//Функция поиска нода по ключу
function TfmConfTree.FindNode(const Node: TTreeNode;
  Key: Integer): TTreeNode;
var
  I: Integer;
  Id: Integer;
begin
  Result := nil;
  if Assigned(Node) then
  begin
    Id := Integer(Node.data);
    if Id = Key then
      Result := Node
    else
      for I := 0 to Node.Count - 1 do
      begin
        Result :=
          FindNode(Node[I], Key);
        if Assigned(Result) then Break;
      end;
  end;

end;
//Функция построения дерева
procedure BuildTree;
var
  I: Integer;
  Root, Node: TTreeNode;
  Tree: TVirtualTreeView;
begin
  Root := Tree.Items.Add(nil, IntToStr(Objects[0].ID));
  for I := 1 to ObjectsCount -1 do
  begin
    Node := FindNode(Root, Objects[I].ParentId);
    if not Assigned(Node) then 
      Tree.AddObject(
        nil, 
        IntToStr(Objects[0].Id), 
        Integer(Objects[0].Id)
      );
    Node := 
      Tree.Items.AddChildObject(
        Node, 
        IntToStr(Objects[0].Id),
        Integer(Objects[0].Id)
      );
  end;
end

//КОД НЕ ПРОВЕРЯЛ, ПИСАЛ ПО ПАМЯТИ

Ну а после, уже можно оптимизировать. Надеюсь, как адаптировать код к VirtualTreeView разберёшься сам

Это сообщение отредактировал(а) cat512 - 26.4.2011, 00:20
PM MAIL   Вверх
Sheleh
Дата 27.4.2011, 03:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 21.4.2011

Репутация: нет
Всего: нет



Всем спасибо, в итоге получилось следующее (код ниже). Для удобства реализации я добавил в свою запись два вара - ссылка на свой нод в VT, и таг, по которому определяется, была ли запись уже отображена в дереве.

Код

type
  Pobjects = ^Tobjects;

  Tobjects = record
    ID, ParentID: integer;
    Name, Num, Time: string;
    items: array[1..16] of string;
    VTTag: Boolean;
    VTPointer : PVirtualNode;
  end;

var
  Objects: array of Tobjects;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  CountObjects:=0;
  VT.NodeDataSize := SizeOf(Tobjects);
end;

procedure TMainForm.Button2Click(Sender: TObject);//процедура добавление итемов в VT
var i: integer;
  Pobject: Pobjects;
function AddVTNode(Index: integer): boolean;
begin
  if Objects[Objects[Index].ParentID].VTTag = False then AddVTNode(Objects[Index].ParentID); //Если родитель объекта не определен - рекурсивно вызываем добавление родителя
  if objects[i].VTTag = false then//после нахождения родителя добавляем ему нод
   begin
     objects[Index].VTPointer:=VT.AddChild(Objects[Objects[Index].ParentID].VTPointer);
     Pobject:= VT.GetNodeData(objects[Index].VTPointer);
     Pobject^:=objects[Index];
     objects[Index].VTTag:=True;
   end
end;

begin
  //добавляем первый нод
  objects[1].VTPointer:=VT.AddChild(nil);
  Pobject:=VT.GetNodeData(objects[1].VTPointer);
  Pobject^:=objects[1];
  Objects[1].VTTag:=True;
 //остальные автоматом
  for i:=2 to CountObjects do AddVTNode(Objects[I].ID);
end;


Из недостатков - код зацикливается, если у объекта нет родителя.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0666 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.