Gérer les connecteurs dans les présentations avec PHP

Un connecteur PowerPoint est une ligne spéciale qui relie ou lie deux formes entre elles et reste attaché aux formes même lorsqu’elles sont déplacées ou repositionnées sur une diapositive donnée.

Les connecteurs sont généralement reliés à des points de connexion (points verts), qui existent par défaut sur toutes les formes. Les points de connexion apparaissent lorsqu’un curseur s’en approche.

Points d’ajustement (points orange), qui n’existent que sur certains connecteurs, sont utilisés pour modifier la position et la forme des connecteurs.

Types de connecteurs

Dans PowerPoint, vous pouvez utiliser des connecteurs droits, coudés (angulaires) et courbes.

Aspose.Slides fournit ces connecteurs :

Connecteur Image Nombre de points d’ajustement
ShapeType::Line shapetype-lineconnector 0
ShapeType::StraightConnector1 shapetype-straightconnector1 0
ShapeType::BentConnector2 shapetype-bent-connector2 0
ShapeType::BentConnector3 shapetype-bentconnector3 1
ShapeType::BentConnector4 shapetype-bentconnector4 2
ShapeType::BentConnector5 shapetype-bentconnector5 3
ShapeType::CurvedConnector2 shapetype-curvedconnector2 0
ShapeType::CurvedConnector3 shapetype-curvedconnector3 1
ShapeType::CurvedConnector4 shapetype-curvedconnector4 2
ShapeType::CurvedConnector5 shapetype.curvedconnector5 3

Connecter des formes à l’aide de connecteurs

  1. Créez une instance de la classe Presentation.
  2. Obtenez une référence à la diapositive via son indice.
  3. Ajoutez deux AutoShape à la diapositive en utilisant la méthode addAutoShape exposée par l’objet Shapes.
  4. Ajoutez un connecteur en utilisant la méthode addConnector exposée par l’objet Shapes en définissant le type de connecteur.
  5. Connectez les formes à l’aide du connecteur.
  6. Appelez la méthode reroute pour appliquer le chemin de connexion le plus court.
  7. Enregistrez la présentation.

Ce code PHP vous montre comment ajouter un connecteur (un connecteur coudé) entre deux formes (une ellipse et un rectangle) :

// Crée une instance d'une classe de présentation qui représente le fichier PPTX
  $pres = new Presentation();
  try {
    # Accède à la collection de formes d'une diapositive spécifique
    $shapes = $pres->getSlides()->get_Item(0)->getShapes();
    # Ajoute une forme auto Ellipse
    $ellipse = $shapes->addAutoShape(ShapeType::Ellipse, 0, 100, 100, 100);
    # Ajoute une forme auto Rectangle
    $rectangle = $shapes->addAutoShape(ShapeType::Rectangle, 100, 300, 100, 100);
    # Ajoute une forme de connecteur à la collection de formes de la diapositive
    $connector = $shapes->addConnector(ShapeType::BentConnector2, 0, 0, 10, 10);
    # Connecte les formes à l'aide du connecteur
    $connector->setStartShapeConnectedTo($ellipse);
    $connector->setEndShapeConnectedTo($rectangle);
    # Appelle reroute qui définit le chemin le plus court automatique entre les formes
    $connector->reroute();
    # Enregistre la présentation
    $pres->save("output.pptx", SaveFormat::Pptx);
} finally {
    if (!java_is_null($pres)) $pres.dispose();
}

Spécifier un point de connexion

Si vous souhaitez qu’un connecteur relie deux formes en utilisant des points spécifiques sur les formes, vous devez spécifier vos points de connexion préférés de cette manière :

  1. Créez une instance de la classe Presentation.
  2. Obtenez une référence à la diapositive via son indice.
  3. Ajoutez deux AutoShape à la diapositive en utilisant la méthode addAutoShape exposée par l’objet Shapes.
  4. Ajoutez un connecteur en utilisant la méthode addConnector exposée par l’objet Shapes en définissant le type de connecteur.
  5. Connectez les formes à l’aide du connecteur.
  6. Définissez vos points de connexion préférés sur les formes.
  7. Enregistrez la présentation.

Ce code PHP montre une opération où un point de connexion préféré est spécifié :

  # Crée une instance d'une classe de présentation qui représente un fichier PPTX
  $pres = new Presentation();
  try {
    # Accède à la collection de formes d'une diapositive spécifique
    $shapes = $pres->getSlides()->get_Item(0)->getShapes();
    # Ajoute une forme auto Ellipse
    $ellipse = $shapes->addAutoShape(ShapeType::Ellipse, 0, 100, 100, 100);
    # Ajoute une forme auto Rectangle
    $rectangle = $shapes->addAutoShape(ShapeType::Rectangle, 100, 300, 100, 100);
    # Ajoute une forme de connecteur à la collection de formes de la diapositive
    $connector = $shapes->addConnector(ShapeType::BentConnector2, 0, 0, 10, 10);
    # Connecte les formes à l'aide du connecteur
    $connector->setStartShapeConnectedTo($ellipse);
    $connector->setEndShapeConnectedTo($rectangle);
    # Définit l'indice du point de connexion préféré sur la forme Ellipse
    $wantedIndex = 6;
    # Vérifie si l'indice préféré est inférieur au nombre maximal d'indices de site
    if ($ellipse->getConnectionSiteCount() > $wantedIndex) {
      # Définit le point de connexion préféré sur la forme auto Ellipse
      $connector->setStartShapeConnectionSiteIndex($wantedIndex);
    }
    # Enregistre la présentation
    $pres->save("output.pptx", SaveFormat::Pptx);
  } finally {
    if (!java_is_null($pres)) {
      $pres->dispose();
    }
  }

Ajuster un point de connecteur

Vous pouvez ajuster un connecteur existant via ses points d’ajustement. Seuls les connecteurs disposant de points d’ajustement peuvent être modifiés de cette façon. Voir le tableau sous Types de connecteurs.

Cas simple

Considérez un cas où un connecteur entre deux formes (A et B) passe à travers une troisième forme (C) :

connector-obstruction

  $pres = new Presentation();
  try {
    $sld = $pres->getSlides()->get_Item(0);
    $shape = $sld->getShapes()->addAutoShape(ShapeType::Rectangle, 300, 150, 150, 75);
    $shapeFrom = $sld->getShapes()->addAutoShape(ShapeType::Rectangle, 500, 400, 100, 50);
    $shapeTo = $sld->getShapes()->addAutoShape(ShapeType::Rectangle, 100, 100, 70, 30);
    $connector = $sld->getShapes()->addConnector(ShapeType::BentConnector5, 20, 20, 400, 300);
    $connector->getLineFormat()->setEndArrowheadStyle(LineArrowheadStyle->Triangle);
    $connector->getLineFormat()->getFillFormat()->setFillType(FillType::Solid);
    $connector->getLineFormat()->getFillFormat()->getSolidFillColor()->setColor(java("java.awt.Color")->BLACK);
    $connector->setStartShapeConnectedTo($shapeFrom);
    $connector->setEndShapeConnectedTo($shapeTo);
    $connector->setStartShapeConnectionSiteIndex(2);
  } finally {
    if (!java_is_null($pres)) {
      $pres->dispose();
    }
  }

Pour éviter ou contourner la troisième forme, nous pouvons ajuster le connecteur en déplaçant sa ligne verticale vers la gauche de cette façon :

connector-obstruction-fixed

  $adj2 = $connector->getAdjustments()->get_Item(1);
  $adj2->setRawValue($adj2->getRawValue() + 10000);

Cas complexes

Pour effectuer des ajustements plus complexes, vous devez prendre en compte les éléments suivants :

  • Le point réglable d’un connecteur est fortement lié à une formule qui calcule et détermine sa position. Ainsi, les changements de l’emplacement du point peuvent modifier la forme du connecteur.
  • Les points d’ajustement d’un connecteur sont définis dans un ordre strict dans un tableau. Les points d’ajustement sont numérotés du point de départ du connecteur à son point d’arrivée.
  • Les valeurs des points d’ajustement reflètent le pourcentage de la largeur/hauteur de la forme du connecteur.
    • La forme est délimitée par les points de début et de fin du connecteur multipliés par 1000.
    • Le premier point, le deuxième point et le troisième point définissent respectivement le pourcentage de la largeur, le pourcentage de la hauteur et à nouveau le pourcentage de la largeur.
  • Pour les calculs déterminant les coordonnées des points d’ajustement d’un connecteur, vous devez tenir compte de la rotation du connecteur et de son reflet. Note que l’angle de rotation de tous les connecteurs affichés sous Types de connecteurs est 0.

Cas 1

Considérez un cas où deux objets de cadre de texte sont reliés entre eux par un connecteur :

connector-shape-complex

  # Instancie une classe de présentation qui représente un fichier PPTX
  $pres = new Presentation();
  try {
    # Récupère la première diapositive de la présentation
    $sld = $pres->getSlides()->get_Item(0);
    # Ajoute des formes qui seront reliées ensemble via un connecteur
    $shapeFrom = $sld->getShapes()->addAutoShape(ShapeType::Rectangle, 100, 100, 60, 25);
    $shapeFrom->getTextFrame()->setText("From");
    $shapeTo = $sld->getShapes()->addAutoShape(ShapeType::Rectangle, 500, 100, 60, 25);
    $shapeTo->getTextFrame()->setText("To");
    # Ajoute un connecteur
    $connector = $sld->getShapes()->addConnector(ShapeType::BentConnector4, 20, 20, 400, 300);
    # Définit la direction du connecteur
    $connector->getLineFormat()->setEndArrowheadStyle(LineArrowheadStyle->Triangle);
    # Définit la couleur du connecteur
    $connector->getLineFormat()->getFillFormat()->setFillType(FillType::Solid);
    $connector->getLineFormat()->getFillFormat()->getSolidFillColor()->setColor(java("java.awt.Color")->RED);
    # Définit l'épaisseur de la ligne du connecteur
    $connector->getLineFormat()->setWidth(3);
    # Lie les formes ensemble avec le connecteur
    $connector->setStartShapeConnectedTo($shapeFrom);
    $connector->setStartShapeConnectionSiteIndex(3);
    $connector->setEndShapeConnectedTo($shapeTo);
    $connector->setEndShapeConnectionSiteIndex(2);
    # Obtient les points d'ajustement du connecteur
    $adjValue_0 = $connector->getAdjustments()->get_Item(0);
    $adjValue_1 = $connector->getAdjustments()->get_Item(1);
  } finally {
    if (!java_is_null($pres)) {
      $pres->dispose();
    }
  }

Ajustement

Nous pouvons modifier les valeurs des points d’ajustement du connecteur en augmentant respectivement le pourcentage de largeur et de hauteur de 20 % et 200 % :

  # Modifie les valeurs des points d'ajustement
  $adjValue_0->setRawValue($adjValue_0->getRawValue() + 20000);
  $adjValue_1->setRawValue($adjValue_1->getRawValue() + 200000);

Le résultat :

connector-adjusted-1

Pour définir un modèle qui nous permet de déterminer les coordonnées et la forme des parties individuelles du connecteur, créons une forme qui correspond à la composante horizontale du connecteur au point connector.getAdjustments().get_Item(0) :

  # Dessine la composante verticale du connecteur
  $x = $connector->getX() . $connector->getWidth() * $adjValue_0->getRawValue() / 100000;
  $y = $connector->getY();
  $height = $connector->getHeight() * $adjValue_1->getRawValue() / 100000;
  $sld->getShapes()->addAutoShape(ShapeType::Rectangle, $x, $y, 0, $height);

Le résultat :

connector-adjusted-2

Cas 2

Dans le Cas 1, nous avons démontré une opération simple d’ajustement de connecteur en utilisant des principes de base. Dans les situations normales, vous devez prendre en compte la rotation du connecteur et son affichage (qui sont définis par connector.getRotation(), connector.getFrame().getFlipH() et connector.getFrame().getFlipV()). Nous allons maintenant démontrer le processus.

Tout d’abord, ajoutons un nouvel objet de cadre de texte (To 1) à la diapositive (à des fins de connexion) et créons un nouveau connecteur (vert) qui le relie aux objets déjà créés.

  # Crée un nouvel objet de liaison
  $shapeTo_1 = $sld->getShapes()->addAutoShape(ShapeType::Rectangle, 100, 400, 60, 25);
  $shapeTo_1->getTextFrame()->setText("To 1");
  # Crée un nouveau connecteur
  $connector = $sld->getShapes()->addConnector(ShapeType::BentConnector4, 20, 20, 400, 300);
  $connector->getLineFormat()->setEndArrowheadStyle(LineArrowheadStyle->Triangle);
  $connector->getLineFormat()->getFillFormat()->setFillType(FillType::Solid);
  $connector->getLineFormat()->getFillFormat()->getSolidFillColor()->setColor(java("java.awt.Color")->CYAN);
  $connector->getLineFormat()->setWidth(3);
  # Connecte les objets en utilisant le connecteur nouvellement créé
  $connector->setStartShapeConnectedTo($shapeFrom);
  $connector->setStartShapeConnectionSiteIndex(2);
  $connector->setEndShapeConnectedTo($shapeTo_1);
  $connector->setEndShapeConnectionSiteIndex(3);
  # Obtient les points d'ajustement du connecteur
  $adjValue_0 = $connector->getAdjustments()->get_Item(0);
  $adjValue_1 = $connector->getAdjustments()->get_Item(1);
  # Modifie les valeurs des points d'ajustement
  $adjValue_0->setRawValue($adjValue_0->getRawValue() + 20000);
  $adjValue_1->setRawValue($adjValue_1->getRawValue() + 200000);

Le résultat :

connector-adjusted-3

Ensuite, créons une forme qui correspondra à la composante horizontale du connecteur qui passe par le nouveau point d’ajustement du connecteur connector.getAdjustments().get_Item(0). Nous utiliserons les valeurs provenant des données du connecteur pour connector.getRotation(), connector.getFrame().getFlipH() et connector.getFrame().getFlipV() et appliquerons la formule de conversion de coordonnées couramment utilisée pour une rotation autour d’un point donné x0 :

X = (x — x0) * cos(alpha) — (y — y0) * sin(alpha) + x0; Y = (x — x0) * sin(alpha) + (y — y0) * cos(alpha) + y0;

Dans notre cas, l’angle de rotation de l’objet est de 90 degrés et le connecteur est affiché verticalement, voici le code correspondant :

  # Enregistre les coordonnées du connecteur
  $x = $connector->getX();
  $y = $connector->getY();
  # Corrige les coordonnées du connecteur si nécessaire
  if ($connector->getFrame()->getFlipH() == NullableBool::True) {
    $x += $connector->getWidth();
  }
  if ($connector->getFrame()->getFlipV() == NullableBool::True) {
    $y += $connector->getHeight();
  }
  # Prend la valeur du point d'ajustement comme coordonnée
  $x += $connector->getWidth() * $adjValue_0->getRawValue() / 100000;
  # Convertit les coordonnées puisqu Sin(90) = 1 et Cos(90) = 0
  $xx = $connector->getFrame()->getCenterX() - $y . $connector->getFrame()->getCenterY();
  $yy = $x - $connector->getFrame()->getCenterX() . $connector->getFrame()->getCenterY();
  # Détermine la largeur de la composante horizontale en utilisant la valeur du second point d'ajustement
  $width = $connector->getHeight() * $adjValue_1->getRawValue() / 100000;
  $shape = $sld->getShapes()->addAutoShape(ShapeType::Rectangle, $xx, $yy, $width, 0);
  $shape->getLineFormat()->getFillFormat()->setFillType(FillType::Solid);
  $shape->getLineFormat()->getFillFormat()->getSolidFillColor()->setColor(java("java.awt.Color")->RED);

Le résultat :

connector-adjusted-4

Nous avons démontré des calculs impliquant des ajustements simples et des points d’ajustement complexes (points d’ajustement avec angles de rotation). En utilisant les connaissances acquises, vous pouvez développer votre propre modèle (ou écrire du code) pour obtenir un objet GraphicsPath ou même définir les valeurs des points d’ajustement d’un connecteur en fonction de coordonnées spécifiques de la diapositive.

Trouver l’angle des lignes de connecteur

  1. Créez une instance de la classe.
  2. Obtenez une référence à la diapositive via son indice.
  3. Accédez à la forme de ligne du connecteur.
  4. Utilisez la largeur, la hauteur, la hauteur du cadre de forme et la largeur du cadre de forme pour calculer l’angle.

Ce code PHP montre une opération dans laquelle nous avons calculé l’angle d’une forme de ligne de connecteur :

  $pres = new Presentation("ConnectorLineAngle.pptx");
  try {
    $slide = $pres->getSlides()->get_Item(0);
    for($i = 0; $i < java_values($slide->getShapes()->size()) ; $i++) {
      $dir = 0.0;
      $shape = $slide->getShapes()->get_Item($i);
      if (java_instanceof($shape, new JavaClass("com.aspose.slides.AutoShape"))) {
        $ashp = $shape;
        if ($ashp->getShapeType() == ShapeType::Line) {
          $dir = getDirection($ashp->getWidth(), $ashp->getHeight(), java_values($ashp->getFrame()->getFlipH()) > 0, $ashp->getFrame()->getFlipV() > 0);
        }
      } else if (java_instanceof($shape, new JavaClass("com.aspose.slides.Connector"))) {
        $ashp = $shape;
        $dir = getDirection($ashp->getWidth(), $ashp->getHeight(), java_values($ashp->getFrame()->getFlipH()) > 0, java_values($ashp->getFrame()->getFlipV()) > 0);
      }
      echo($dir);
    }
  } finally {
    if (!java_is_null($pres)) {
      $pres->dispose();
    }
  }

FAQ

Comment savoir si un connecteur peut être « collé » à une forme spécifique ?

Vérifiez que la forme expose des sites de connexion. S’il n’y en a pas ou si le nombre est zéro, le collage n’est pas disponible ; dans ce cas, utilisez des extrémités libres et positionnez-les manuellement. Il est judicieux de vérifier le nombre de sites avant d’attacher.

Que se passe-t-il pour un connecteur si je supprime l’une des formes connectées ?

Ses extrémités seront détachées ; le connecteur reste sur la diapositive comme une ligne ordinaire avec un départ/arrivée libre. Vous pouvez soit le supprimer, soit réassigner les connexions et, si nécessaire, reroute.

Les liaisons de connecteur sont-elles conservées lors de la copie d’une diapositive vers une autre présentation ?

En général oui, à condition que les formes cibles soient également copiées. Si la diapositive est insérée dans un autre fichier sans les formes connectées, les extrémités deviennent libres et vous devrez les rattacher.