Copiando e Colando

Modelos

O design do IBM® ILOG® Dojo Diagrammer pode ser dividido em dois cenários principais:
no primeiro cenário, o widget Diagrama é usado para exibir o conteúdo de um armazenamento de dados como um diagrama.
no segundo cenário, um Selection geralmente é composto de formas GFX que são criadas no nível da interface com o usuário e não estão ligadas ao armazenamento de dados.
Esta divisão afeta a funcionalidade copiar e colar. No primeiro cenário, se você copiar e colar conteúdo em um armazenamento de dados, a duplicação ocorrerá no armazenamento de dados e os gráficos refletirão a mudança por meio de atualizações de dependência. No segundo cenário, a duplicação ocorre no nível de GFX. Um usuário também pode desejar que os dados do usuário sejam armazenados e aplicados nas operações copiar e colar, incluindo dados do usuário que não estão visíveis no momento. Estas operações produzem resultados diferentes, dependendo do cenário usado.
Para abordar esta variabilidade, o IBM® ILOG® Dojo Diagrammer fornece uma biblioteca com operações de modelo que permitem implementar customizações.

Representação

A representação de elementos copiados deve ser independente do contexto. Por exemplo, a representação deve estar presente, mesmo que não haja nenhuma superfície GFX ativa (por exemplo, quando não houver nenhuma conexão DataStore). A representação é semelhante ao algoritmo de serialização em dojox.gfx, que possui esta propriedade (independente de plataforma/renderizador). A serialização converte objetos GFX em uma representação de objeto JavaScript compatível com JSON, independente do renderizador e da existência da superfície. O mesmo conceito é aplicado para representar formas copiadas.

Serialização e Desserialização

A classe Serializer manipula a lógica de esqueleto para serialização e, em específico, operações copiar e colar. As operações de cópia são serializadas na área de transferência e as operações de colagem são desserializadas da área de transferência.
A classe ibm_ilog.diagram.util.Serializer possui um conjunto de retornos de chamada do usuário que manipulam os detalhes mais precisos dos dados que são copiados. Os retornos de chamada incluem uma função para obter os identificadores associados a entidades copiadas e uma função de serialização para cada entidade em um gráfico.
Os retornos de chamada de serialização geram e retornam a representação da entidade associada. Esses dados são usados pelo retorno de chamada do usuário associado para desserialização, portanto, você deve colocar todos os dados necessários para reconstrução da entidade no contexto adequado.
Os retornos de chamada de desserialização criam novas entidades com base em sua representação existente. Estes retornos de chamada recebem os dados serializados pelos retornos de chamada do usuário, incluindo um dicionário por ID de todas as novas entidades já criadas no processo de desserialização e o contêiner no qual a nova entidade é criada pelo retorno de chamada atual. Um retorno de chamada de desserialização também deve retornar um objeto que representa a entidade recém-criada por meio da desserialização. Este valor é armazenado no dicionário para chamadas de retorno de chamada adicionais no processo e é transmitido como o argumento de contêiner em chamadas para os filhos da entidade (no caso de subgráficos).
Os seguintes retornos de chamada são usados nos processos de serialização e desserialização:
  • getId identifica elementos do gráfico serializados por meio do processo de serialização/desserialização.
  • serializeNodeData é usado para serializar um nó. Use esta função de retorno de chamada para criar a representação apropriada para um nó que posteriormente será usado pela função de desserialização correspondente.
  • serializeLinkData é usado para serializar um link. Use esta função de retorno de chamada para criar a representação apropriada para um link que posteriormente será usado pela função de desserialização correspondente.
  • serializeSubgraphData é usado para serializar um subgráfico. Use esta função de retorno de chamada para criar a representação apropriada para um subgráfico que posteriormente será usado pela função de desserialização correspondente.
  • deserializeNodeData desserializa um nó dos dados serializados para o contêiner especificado.
  • deserializeLinkData desserializa um link dos dados serializados para o contêiner especificado.
  • deserializeSubgraphData desserializa um subgráfico dos dados serializados para o contêiner especificado.
Para customizações de copiar e colar, chame a função serialize(entity) e, em seguida, a função deserialize(representation,container). O argumento entity é o objeto que é serializado. O argumento representation é o resultado obtido da chamada anterior para serialize e container é o objeto compatível com os objetos definidos pelo usuário retornados no retorno de chamada deserializeSubgraph. A função deserialize coleta os resultados dos retornos de chamada do usuário e retorna-os em uma estrutura de dados.

Exemplo

O exemplo a seguir mostra como gravar um serializador de gráfico baseado no armazenamento de dados básico:
var serializer = new ibm_ilog.diagram.util.Serializer({
   getId: function(ge) {
      return ge.getId();
   },
   serializeNodeData: function(ge){
      return {
         transform:m.clone(ge.getTransform())
      };
   },
   deserializeNodeData: function(s,newByOldId,container){
      var node = container.graph.createNode();
      node.setTransform(s.transform);
      return {created:node};
   },
   serializeSubgraphData: function(ge){
      return {
         transform:m.clone(ge.getTransform())
      };
   },
   deserializeSubgraphData: function(s,newByOldId,container){
      var sg = container.graph.createSubgraph();
      sg.setTransform(s.transform);
      return {created:sg,graph:sg.getGraph()};
   },
   serializeLinkData: function(ge){
      return {
         startId:ge.getStartNode().getId(),
         endId:ge.getEndNode().getId()
      };
   },
   deserializeLinkData: function(s,newByOldId,container){
      var link = container.graph.createLink();
      link.setStartNode(newByOldId.item(s.startId).created);
      link.setEndNode(newByOldId.item(s.endId).created);
      return {created:link};
   }
});