[Workflow] Add colors to workflow dumps
This commit is contained in:
parent
50ff35f1d7
commit
60ad109533
@ -6,6 +6,19 @@ CHANGELOG
|
||||
|
||||
* Trigger `entered` event for subject entering in the Workflow for the first time
|
||||
* Added a context to `Workflow::apply()`. The `MethodMarkingStore` could be used to leverage this feature.
|
||||
* Add style to transitions by declaring metadata:
|
||||
```
|
||||
$places = range('a', 'b');
|
||||
$transition = new Transition('t1', 'a', 'b');
|
||||
$transitions[] = $transition;
|
||||
$transitionsMetadata = new \SplObjectStorage();
|
||||
$transitionsMetadata[$transition] = [
|
||||
'color' => 'Red',
|
||||
'arrow_color' => '#00ff00',
|
||||
];
|
||||
$inMemoryMetadataStore = new InMemoryMetadataStore([], [], $transitionsMetadata);
|
||||
return new Definition($places, $transitions, null, $inMemoryMetadataStore);
|
||||
```
|
||||
|
||||
4.1.0
|
||||
-----
|
||||
|
@ -63,6 +63,8 @@ class GraphvizDumper implements DumperInterface
|
||||
*/
|
||||
protected function findPlaces(Definition $definition, Marking $marking = null)
|
||||
{
|
||||
$workflowMetadata = $definition->getMetadataStore();
|
||||
|
||||
$places = [];
|
||||
|
||||
foreach ($definition->getPlaces() as $place) {
|
||||
@ -74,6 +76,15 @@ class GraphvizDumper implements DumperInterface
|
||||
$attributes['color'] = '#FF0000';
|
||||
$attributes['shape'] = 'doublecircle';
|
||||
}
|
||||
$backgroundColor = $workflowMetadata->getMetadata('bg_color', $place);
|
||||
if (null !== $backgroundColor) {
|
||||
$attributes['style'] = 'filled';
|
||||
$attributes['fillcolor'] = $backgroundColor;
|
||||
}
|
||||
$label = $workflowMetadata->getMetadata('label', $place);
|
||||
if (null !== $label) {
|
||||
$attributes['name'] = $label;
|
||||
}
|
||||
$places[$place] = [
|
||||
'attributes' => $attributes,
|
||||
];
|
||||
@ -87,12 +98,23 @@ class GraphvizDumper implements DumperInterface
|
||||
*/
|
||||
protected function findTransitions(Definition $definition)
|
||||
{
|
||||
$workflowMetadata = $definition->getMetadataStore();
|
||||
|
||||
$transitions = [];
|
||||
|
||||
foreach ($definition->getTransitions() as $transition) {
|
||||
$attributes = ['shape' => 'box', 'regular' => true];
|
||||
|
||||
$backgroundColor = $workflowMetadata->getMetadata('bg_color', $transition);
|
||||
if (null !== $backgroundColor) {
|
||||
$attributes['style'] = 'filled';
|
||||
$attributes['fillcolor'] = $backgroundColor;
|
||||
}
|
||||
$name = $workflowMetadata->getMetadata('label', $transition) ?? $transition->getName();
|
||||
|
||||
$transitions[] = [
|
||||
'attributes' => ['shape' => 'box', 'regular' => true],
|
||||
'name' => $transition->getName(),
|
||||
'attributes' => $attributes,
|
||||
'name' => $name,
|
||||
];
|
||||
}
|
||||
|
||||
@ -107,7 +129,14 @@ class GraphvizDumper implements DumperInterface
|
||||
$code = '';
|
||||
|
||||
foreach ($places as $id => $place) {
|
||||
$code .= sprintf(" place_%s [label=\"%s\", shape=circle%s];\n", $this->dotize($id), $this->escape($id), $this->addAttributes($place['attributes']));
|
||||
if (isset($place['attributes']['name'])) {
|
||||
$placeName = $place['attributes']['name'];
|
||||
unset($place['attributes']['name']);
|
||||
} else {
|
||||
$placeName = $id;
|
||||
}
|
||||
|
||||
$code .= sprintf(" place_%s [label=\"%s\", shape=circle%s];\n", $this->dotize($id), $this->escape($placeName), $this->addAttributes($place['attributes']));
|
||||
}
|
||||
|
||||
return $code;
|
||||
@ -121,7 +150,7 @@ class GraphvizDumper implements DumperInterface
|
||||
$code = '';
|
||||
|
||||
foreach ($transitions as $place) {
|
||||
$code .= sprintf(" transition_%s [label=\"%s\", shape=box%s];\n", $this->dotize($place['name']), $this->escape($place['name']), $this->addAttributes($place['attributes']));
|
||||
$code .= sprintf(" transition_%s [label=\"%s\",%s];\n", $this->dotize($place['name']), $this->escape($place['name']), $this->addAttributes($place['attributes']));
|
||||
}
|
||||
|
||||
return $code;
|
||||
@ -132,19 +161,23 @@ class GraphvizDumper implements DumperInterface
|
||||
*/
|
||||
protected function findEdges(Definition $definition)
|
||||
{
|
||||
$workflowMetadata = $definition->getMetadataStore();
|
||||
|
||||
$dotEdges = [];
|
||||
|
||||
foreach ($definition->getTransitions() as $transition) {
|
||||
$transitionName = $workflowMetadata->getMetadata('label', $transition) ?? $transition->getName();
|
||||
|
||||
foreach ($transition->getFroms() as $from) {
|
||||
$dotEdges[] = [
|
||||
'from' => $from,
|
||||
'to' => $transition->getName(),
|
||||
'to' => $transitionName,
|
||||
'direction' => 'from',
|
||||
];
|
||||
}
|
||||
foreach ($transition->getTos() as $to) {
|
||||
$dotEdges[] = [
|
||||
'from' => $transition->getName(),
|
||||
'from' => $transitionName,
|
||||
'to' => $to,
|
||||
'direction' => 'to',
|
||||
];
|
||||
@ -209,7 +242,7 @@ class GraphvizDumper implements DumperInterface
|
||||
return \is_bool($value) ? ($value ? '1' : '0') : \addslashes($value);
|
||||
}
|
||||
|
||||
private function addAttributes(array $attributes): string
|
||||
protected function addAttributes(array $attributes): string
|
||||
{
|
||||
$code = [];
|
||||
|
||||
@ -217,7 +250,7 @@ class GraphvizDumper implements DumperInterface
|
||||
$code[] = sprintf('%s="%s"', $k, $this->escape($v));
|
||||
}
|
||||
|
||||
return $code ? ', '.implode(', ', $code) : '';
|
||||
return $code ? ' '.implode(' ', $code) : '';
|
||||
}
|
||||
|
||||
private function addOptions(array $options): string
|
||||
|
@ -14,6 +14,8 @@ namespace Symfony\Component\Workflow\Dumper;
|
||||
use InvalidArgumentException;
|
||||
use Symfony\Component\Workflow\Definition;
|
||||
use Symfony\Component\Workflow\Marking;
|
||||
use Symfony\Component\Workflow\Metadata\MetadataStoreInterface;
|
||||
use Symfony\Component\Workflow\Transition;
|
||||
|
||||
/**
|
||||
* PlantUmlDumper dumps a workflow as a PlantUML file.
|
||||
@ -63,13 +65,13 @@ class PlantUmlDumper implements DumperInterface
|
||||
public function dump(Definition $definition, Marking $marking = null, array $options = []): string
|
||||
{
|
||||
$options = array_replace_recursive(self::DEFAULT_OPTIONS, $options);
|
||||
$code = $this->initialize($options);
|
||||
|
||||
$workflowMetadata = $definition->getMetadataStore();
|
||||
|
||||
$code = $this->initialize($options, $definition);
|
||||
|
||||
foreach ($definition->getPlaces() as $place) {
|
||||
$placeEscaped = $this->escape($place);
|
||||
$code[] =
|
||||
"state $placeEscaped".
|
||||
($definition->getInitialPlace() === $place ? ' '.self::INITIAL : '').
|
||||
($marking && $marking->has($place) ? ' '.self::MARKED : '');
|
||||
$code[] = $this->getState($place, $definition, $marking);
|
||||
}
|
||||
if ($this->isWorkflowTransitionType()) {
|
||||
foreach ($definition->getTransitions() as $transition) {
|
||||
@ -83,10 +85,26 @@ class PlantUmlDumper implements DumperInterface
|
||||
$fromEscaped = $this->escape($from);
|
||||
foreach ($transition->getTos() as $to) {
|
||||
$toEscaped = $this->escape($to);
|
||||
|
||||
$transitionEscapedWithStyle = $this->getTransitionEscapedWithStyle($workflowMetadata, $transition, $transitionEscaped);
|
||||
|
||||
$arrowColor = $workflowMetadata->getMetadata('arrow_color', $transition);
|
||||
|
||||
$transitionColor = '';
|
||||
if (null !== $arrowColor) {
|
||||
$transitionColor = $this->getTransitionColor($arrowColor) ?? '';
|
||||
}
|
||||
|
||||
if ($this->isWorkflowTransitionType()) {
|
||||
$transitionLabel = '';
|
||||
// Add label only if it has a style
|
||||
if ($transitionEscapedWithStyle != $transitionEscaped) {
|
||||
$transitionLabel = ": $transitionEscapedWithStyle";
|
||||
}
|
||||
|
||||
$lines = [
|
||||
"$fromEscaped --> $transitionEscaped",
|
||||
"$transitionEscaped --> $toEscaped",
|
||||
"$fromEscaped -${transitionColor}-> ${transitionEscaped}${transitionLabel}",
|
||||
"$transitionEscaped -${transitionColor}-> ${toEscaped}${transitionLabel}",
|
||||
];
|
||||
foreach ($lines as $line) {
|
||||
if (!\in_array($line, $code)) {
|
||||
@ -94,7 +112,7 @@ class PlantUmlDumper implements DumperInterface
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$code[] = "$fromEscaped --> $toEscaped: $transitionEscaped";
|
||||
$code[] = "$fromEscaped -${transitionColor}-> $toEscaped: $transitionEscapedWithStyle";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,8 +144,10 @@ class PlantUmlDumper implements DumperInterface
|
||||
return implode(PHP_EOL, $code);
|
||||
}
|
||||
|
||||
private function initialize(array $options): array
|
||||
private function initialize(array $options, Definition $definition): array
|
||||
{
|
||||
$workflowMetadata = $definition->getMetadataStore();
|
||||
|
||||
$code = [];
|
||||
if (isset($options['title'])) {
|
||||
$code[] = "title {$options['title']}";
|
||||
@ -135,6 +155,17 @@ class PlantUmlDumper implements DumperInterface
|
||||
if (isset($options['name'])) {
|
||||
$code[] = "title {$options['name']}";
|
||||
}
|
||||
|
||||
// Add style from nodes
|
||||
foreach ($definition->getPlaces() as $place) {
|
||||
$backgroundColor = $workflowMetadata->getMetadata('bg_color', $place);
|
||||
if (null !== $backgroundColor) {
|
||||
$key = 'BackgroundColor<<'.$this->getColorId($backgroundColor).'>>';
|
||||
|
||||
$options['skinparams']['state'][$key] = $backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['skinparams']) && \is_array($options['skinparams'])) {
|
||||
foreach ($options['skinparams'] as $skinparamKey => $skinparamValue) {
|
||||
if (!$this->isWorkflowTransitionType() && 'agent' === $skinparamKey) {
|
||||
@ -160,4 +191,62 @@ class PlantUmlDumper implements DumperInterface
|
||||
// It's not possible to escape property double quote, so let's remove it
|
||||
return '"'.str_replace('"', '', $string).'"';
|
||||
}
|
||||
|
||||
private function getState(string $place, Definition $definition, Marking $marking = null): string
|
||||
{
|
||||
$workflowMetadata = $definition->getMetadataStore();
|
||||
|
||||
$placeEscaped = $this->escape($place);
|
||||
|
||||
$output = "state $placeEscaped".
|
||||
($definition->getInitialPlace() === $place ? ' '.self::INITIAL : '').
|
||||
($marking && $marking->has($place) ? ' '.self::MARKED : '');
|
||||
|
||||
$backgroundColor = $workflowMetadata->getMetadata('bg_color', $place);
|
||||
if (null !== $backgroundColor) {
|
||||
$output .= ' <<'.$this->getColorId($backgroundColor).'>>';
|
||||
}
|
||||
|
||||
$description = $workflowMetadata->getMetadata('description', $place);
|
||||
if (null !== $description) {
|
||||
$output .= ' as '.$place.
|
||||
PHP_EOL.
|
||||
$place.' : '.$description;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function getTransitionEscapedWithStyle(MetadataStoreInterface $workflowMetadata, Transition $transition, string $to): string
|
||||
{
|
||||
$to = $workflowMetadata->getMetadata('label', $transition) ?? $to;
|
||||
|
||||
$color = $workflowMetadata->getMetadata('color', $transition) ?? null;
|
||||
|
||||
if (null !== $color) {
|
||||
$to = sprintf(
|
||||
'<font color=%1$s>%2$s</font>',
|
||||
$color,
|
||||
$to
|
||||
);
|
||||
}
|
||||
|
||||
return $this->escape($to);
|
||||
}
|
||||
|
||||
private function getTransitionColor(string $color): string
|
||||
{
|
||||
// PUML format requires that color in transition have to be prefixed with “#”.
|
||||
if ('#' !== substr($color, 0, 1)) {
|
||||
$color = '#'.$color;
|
||||
}
|
||||
|
||||
return sprintf('[%s]', $color);
|
||||
}
|
||||
|
||||
private function getColorId(string $color): string
|
||||
{
|
||||
// Remove “#“ from start of the color name so it can be used as an identifier.
|
||||
return ltrim($color, '#');
|
||||
}
|
||||
}
|
||||
|
@ -46,15 +46,32 @@ class StateMachineGraphvizDumper extends GraphvizDumper
|
||||
*/
|
||||
protected function findEdges(Definition $definition)
|
||||
{
|
||||
$workflowMetadata = $definition->getMetadataStore();
|
||||
|
||||
$edges = [];
|
||||
|
||||
foreach ($definition->getTransitions() as $transition) {
|
||||
$attributes = [];
|
||||
|
||||
$transitionName = $workflowMetadata->getMetadata('label', $transition) ?? $transition->getName();
|
||||
|
||||
$labelColor = $workflowMetadata->getMetadata('color', $transition);
|
||||
if (null !== $labelColor) {
|
||||
$attributes['fontcolor'] = $labelColor;
|
||||
}
|
||||
$arrowColor = $workflowMetadata->getMetadata('arrow_color', $transition);
|
||||
if (null !== $arrowColor) {
|
||||
$attributes['color'] = $arrowColor;
|
||||
}
|
||||
|
||||
foreach ($transition->getFroms() as $from) {
|
||||
foreach ($transition->getTos() as $to) {
|
||||
$edges[$from][] = [
|
||||
'name' => $transition->getName(),
|
||||
$edge = [
|
||||
'name' => $transitionName,
|
||||
'to' => $to,
|
||||
'attributes' => $attributes,
|
||||
];
|
||||
$edges[$from][] = $edge;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,7 +88,14 @@ class StateMachineGraphvizDumper extends GraphvizDumper
|
||||
|
||||
foreach ($edges as $id => $edges) {
|
||||
foreach ($edges as $edge) {
|
||||
$code .= sprintf(" place_%s -> place_%s [label=\"%s\" style=\"%s\"];\n", $this->dotize($id), $this->dotize($edge['to']), $this->escape($edge['name']), 'solid');
|
||||
$code .= sprintf(
|
||||
" place_%s -> place_%s [label=\"%s\" style=\"%s\"%s];\n",
|
||||
$this->dotize($id),
|
||||
$this->dotize($edge['to']),
|
||||
$this->escape($edge['name']),
|
||||
'solid',
|
||||
$this->addAttributes($edge['attributes'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,27 +66,27 @@ class GraphvizDumperTest extends TestCase
|
||||
node [fontsize="9" fontname="Arial" color="#333333" fillcolor="lightblue" fixedsize="false" width="1"];
|
||||
edge [fontsize="9" fontname="Arial" color="#333333" arrowhead="normal" arrowsize="0.5"];
|
||||
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle, style="filled"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="b", shape=circle, color="#FF0000", shape="doublecircle"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle style="filled"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="b", shape=circle color="#FF0000" shape="doublecircle"];
|
||||
place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="c", shape=circle];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 [label="d", shape=circle];
|
||||
place_58e6b3a414a1e090dfc6029add0f3555ccba127f [label="e", shape=circle];
|
||||
place_4a0a19218e082a343a1b17e5333409af9d98f0f5 [label="f", shape=circle];
|
||||
place_54fd1711209fb1c0781092374132c66e79e2241b [label="g", shape=circle];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f [label="t1", shape=box, shape="box", regular="1"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [label="t2", shape=box, shape="box", regular="1"];
|
||||
transition_4358694eeb098c6708ae914a10562ce722bbbc34 [label="t3", shape=box, shape="box", regular="1"];
|
||||
transition_a9dfb15be45a5f3128784c80c733f2cdee2f756a [label="t4", shape=box, shape="box", regular="1"];
|
||||
transition_bf55e75fa263cbbc2529db49da43cb7f1d370b88 [label="t5", shape=box, shape="box", regular="1"];
|
||||
transition_e92a96c0e3a20d87ace74ab7871931a8f9f25943 [label="t6", shape=box, shape="box", regular="1"];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f [label="t1", shape="box" regular="1"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [label="t2", shape="box" regular="1"];
|
||||
transition_0e93386f7fc29aa558e22918bd39c3de8c84f6d8 [label="My custom transition label 1", shape="box" regular="1"];
|
||||
transition_a9dfb15be45a5f3128784c80c733f2cdee2f756a [label="t4", shape="box" regular="1"];
|
||||
transition_bf55e75fa263cbbc2529db49da43cb7f1d370b88 [label="t5", shape="box" regular="1"];
|
||||
transition_e92a96c0e3a20d87ace74ab7871931a8f9f25943 [label="t6", shape="box" regular="1"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 -> transition_e5353879bd69bfddcb465dad176ff52db8319d6f [style="solid"];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [style="solid"];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f -> place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [style="solid"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 -> transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [style="solid"];
|
||||
place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 -> transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [style="solid"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d -> place_3c363836cf4e16666669a25da280a1865c2d2874 [style="solid"];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 -> transition_4358694eeb098c6708ae914a10562ce722bbbc34 [style="solid"];
|
||||
transition_4358694eeb098c6708ae914a10562ce722bbbc34 -> place_58e6b3a414a1e090dfc6029add0f3555ccba127f [style="solid"];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 -> transition_0e93386f7fc29aa558e22918bd39c3de8c84f6d8 [style="solid"];
|
||||
transition_0e93386f7fc29aa558e22918bd39c3de8c84f6d8 -> place_58e6b3a414a1e090dfc6029add0f3555ccba127f [style="solid"];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 -> transition_a9dfb15be45a5f3128784c80c733f2cdee2f756a [style="solid"];
|
||||
transition_a9dfb15be45a5f3128784c80c733f2cdee2f756a -> place_4a0a19218e082a343a1b17e5333409af9d98f0f5 [style="solid"];
|
||||
place_58e6b3a414a1e090dfc6029add0f3555ccba127f -> transition_bf55e75fa263cbbc2529db49da43cb7f1d370b88 [style="solid"];
|
||||
@ -104,13 +104,13 @@ class GraphvizDumperTest extends TestCase
|
||||
node [fontsize="9" fontname="Arial" color="#333333" fillcolor="lightblue" fixedsize="false" width="1"];
|
||||
edge [fontsize="9" fontname="Arial" color="#333333" arrowhead="normal" arrowsize="0.5"];
|
||||
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle, style="filled"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle style="filled"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="b", shape=circle];
|
||||
place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="c", shape=circle, color="#FF0000", shape="doublecircle"];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f [label="t1", shape=box, shape="box", regular="1"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [label="t2", shape=box, shape="box", regular="1"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 -> transition_e5353879bd69bfddcb465dad176ff52db8319d6f [style="solid"];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [style="solid"];
|
||||
place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="c", shape=circle color="#FF0000" shape="doublecircle" style="filled" fillcolor="DeepSkyBlue"];
|
||||
transition_805bac6f9261aaae4068bf114e182e9c37e2728d [label="My custom transition label 2", shape="box" regular="1"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [label="t2", shape="box" regular="1"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 -> transition_805bac6f9261aaae4068bf114e182e9c37e2728d [style="solid"];
|
||||
transition_805bac6f9261aaae4068bf114e182e9c37e2728d -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [style="solid"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 -> transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [style="solid"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d -> place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [style="solid"];
|
||||
}
|
||||
@ -124,27 +124,27 @@ class GraphvizDumperTest extends TestCase
|
||||
node [fontsize="9" fontname="Arial" color="#333333" fillcolor="lightblue" fixedsize="false" width="1"];
|
||||
edge [fontsize="9" fontname="Arial" color="#333333" arrowhead="normal" arrowsize="0.5"];
|
||||
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle, style="filled"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle style="filled"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="b", shape=circle];
|
||||
place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="c", shape=circle];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 [label="d", shape=circle];
|
||||
place_58e6b3a414a1e090dfc6029add0f3555ccba127f [label="e", shape=circle];
|
||||
place_4a0a19218e082a343a1b17e5333409af9d98f0f5 [label="f", shape=circle];
|
||||
place_54fd1711209fb1c0781092374132c66e79e2241b [label="g", shape=circle];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f [label="t1", shape=box, shape="box", regular="1"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [label="t2", shape=box, shape="box", regular="1"];
|
||||
transition_4358694eeb098c6708ae914a10562ce722bbbc34 [label="t3", shape=box, shape="box", regular="1"];
|
||||
transition_a9dfb15be45a5f3128784c80c733f2cdee2f756a [label="t4", shape=box, shape="box", regular="1"];
|
||||
transition_bf55e75fa263cbbc2529db49da43cb7f1d370b88 [label="t5", shape=box, shape="box", regular="1"];
|
||||
transition_e92a96c0e3a20d87ace74ab7871931a8f9f25943 [label="t6", shape=box, shape="box", regular="1"];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f [label="t1", shape="box" regular="1"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [label="t2", shape="box" regular="1"];
|
||||
transition_0e93386f7fc29aa558e22918bd39c3de8c84f6d8 [label="My custom transition label 1", shape="box" regular="1"];
|
||||
transition_a9dfb15be45a5f3128784c80c733f2cdee2f756a [label="t4", shape="box" regular="1"];
|
||||
transition_bf55e75fa263cbbc2529db49da43cb7f1d370b88 [label="t5", shape="box" regular="1"];
|
||||
transition_e92a96c0e3a20d87ace74ab7871931a8f9f25943 [label="t6", shape="box" regular="1"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 -> transition_e5353879bd69bfddcb465dad176ff52db8319d6f [style="solid"];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [style="solid"];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f -> place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [style="solid"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 -> transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [style="solid"];
|
||||
place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 -> transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [style="solid"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d -> place_3c363836cf4e16666669a25da280a1865c2d2874 [style="solid"];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 -> transition_4358694eeb098c6708ae914a10562ce722bbbc34 [style="solid"];
|
||||
transition_4358694eeb098c6708ae914a10562ce722bbbc34 -> place_58e6b3a414a1e090dfc6029add0f3555ccba127f [style="solid"];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 -> transition_0e93386f7fc29aa558e22918bd39c3de8c84f6d8 [style="solid"];
|
||||
transition_0e93386f7fc29aa558e22918bd39c3de8c84f6d8 -> place_58e6b3a414a1e090dfc6029add0f3555ccba127f [style="solid"];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 -> transition_a9dfb15be45a5f3128784c80c733f2cdee2f756a [style="solid"];
|
||||
transition_a9dfb15be45a5f3128784c80c733f2cdee2f756a -> place_4a0a19218e082a343a1b17e5333409af9d98f0f5 [style="solid"];
|
||||
place_58e6b3a414a1e090dfc6029add0f3555ccba127f -> transition_bf55e75fa263cbbc2529db49da43cb7f1d370b88 [style="solid"];
|
||||
@ -162,13 +162,13 @@ class GraphvizDumperTest extends TestCase
|
||||
node [fontsize="9" fontname="Arial" color="#333333" fillcolor="lightblue" fixedsize="false" width="1"];
|
||||
edge [fontsize="9" fontname="Arial" color="#333333" arrowhead="normal" arrowsize="0.5"];
|
||||
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle, style="filled"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle style="filled"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="b", shape=circle];
|
||||
place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="c", shape=circle];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f [label="t1", shape=box, shape="box", regular="1"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [label="t2", shape=box, shape="box", regular="1"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 -> transition_e5353879bd69bfddcb465dad176ff52db8319d6f [style="solid"];
|
||||
transition_e5353879bd69bfddcb465dad176ff52db8319d6f -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [style="solid"];
|
||||
place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="c", shape=circle style="filled" fillcolor="DeepSkyBlue"];
|
||||
transition_805bac6f9261aaae4068bf114e182e9c37e2728d [label="My custom transition label 2", shape="box" regular="1"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [label="t2", shape="box" regular="1"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 -> transition_805bac6f9261aaae4068bf114e182e9c37e2728d [style="solid"];
|
||||
transition_805bac6f9261aaae4068bf114e182e9c37e2728d -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [style="solid"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 -> transition_2a5bd02710e975a7fbb92da876655950fbd5e70d [style="solid"];
|
||||
transition_2a5bd02710e975a7fbb92da876655950fbd5e70d -> place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [style="solid"];
|
||||
}
|
||||
|
@ -30,13 +30,13 @@ digraph workflow {
|
||||
node [fontsize="9" fontname="Arial" color="#333333" fillcolor="lightblue" fixedsize="false" width="1"];
|
||||
edge [fontsize="9" fontname="Arial" color="#333333" arrowhead="normal" arrowsize="0.5"];
|
||||
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle, style="filled"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle style="filled"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="b", shape=circle];
|
||||
place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="c", shape=circle];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 [label="d", shape=circle];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="t1" style="solid"];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="t1" style="solid"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 -> place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="t2" style="solid"];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="My custom transition label 3" style="solid" fontcolor="Grey" color="Red"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 -> place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="t2" style="solid" color="Blue"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 -> place_3c363836cf4e16666669a25da280a1865c2d2874 [label="t3" style="solid"];
|
||||
}
|
||||
|
||||
@ -56,13 +56,13 @@ digraph workflow {
|
||||
node [fontsize="9" fontname="Arial" color="#333333" fillcolor="lightblue" fixedsize="false" width="1"];
|
||||
edge [fontsize="9" fontname="Arial" color="#333333" arrowhead="normal" arrowsize="0.5"];
|
||||
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle, style="filled"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="b", shape=circle, color="#FF0000", shape="doublecircle"];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 [label="a", shape=circle style="filled"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="b", shape=circle color="#FF0000" shape="doublecircle"];
|
||||
place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="c", shape=circle];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 [label="d", shape=circle];
|
||||
place_86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="t1" style="solid"];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="t1" style="solid"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 -> place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="t2" style="solid"];
|
||||
place_3c363836cf4e16666669a25da280a1865c2d2874 -> place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 [label="My custom transition label 3" style="solid" fontcolor="Grey" color="Red"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 -> place_84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 [label="t2" style="solid" color="Blue"];
|
||||
place_e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 -> place_3c363836cf4e16666669a25da280a1865c2d2874 [label="t3" style="solid"];
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Symfony\Component\Workflow\Tests;
|
||||
|
||||
use Symfony\Component\Workflow\Definition;
|
||||
use Symfony\Component\Workflow\Metadata\InMemoryMetadataStore;
|
||||
use Symfony\Component\Workflow\Transition;
|
||||
|
||||
trait WorkflowBuilderTrait
|
||||
@ -14,12 +15,21 @@ trait WorkflowBuilderTrait
|
||||
$transitions = [];
|
||||
$transitions[] = new Transition('t1', 'a', ['b', 'c']);
|
||||
$transitions[] = new Transition('t2', ['b', 'c'], 'd');
|
||||
$transitions[] = new Transition('t3', 'd', 'e');
|
||||
$transitionWithMetadataDumpStyle = new Transition('t3', 'd', 'e');
|
||||
$transitions[] = $transitionWithMetadataDumpStyle;
|
||||
$transitions[] = new Transition('t4', 'd', 'f');
|
||||
$transitions[] = new Transition('t5', 'e', 'g');
|
||||
$transitions[] = new Transition('t6', 'f', 'g');
|
||||
|
||||
return new Definition($places, $transitions);
|
||||
$transitionsMetadata = new \SplObjectStorage();
|
||||
$transitionsMetadata[$transitionWithMetadataDumpStyle] = [
|
||||
'label' => 'My custom transition label 1',
|
||||
'color' => 'Red',
|
||||
'arrow_color' => 'Green',
|
||||
];
|
||||
$inMemoryMetadataStore = new InMemoryMetadataStore([], [], $transitionsMetadata);
|
||||
|
||||
return new Definition($places, $transitions, null, $inMemoryMetadataStore);
|
||||
|
||||
// The graph looks like:
|
||||
// +---+ +----+ +---+ +----+ +----+ +----+ +----+ +----+ +---+
|
||||
@ -38,10 +48,28 @@ trait WorkflowBuilderTrait
|
||||
$places = range('a', 'c');
|
||||
|
||||
$transitions = [];
|
||||
$transitions[] = new Transition('t1', 'a', 'b');
|
||||
$transitions[] = new Transition('t2', 'b', 'c');
|
||||
$transitionWithMetadataDumpStyle = new Transition('t1', 'a', 'b');
|
||||
$transitions[] = $transitionWithMetadataDumpStyle;
|
||||
$transitionWithMetadataArrowColorPink = new Transition('t2', 'b', 'c');
|
||||
$transitions[] = $transitionWithMetadataArrowColorPink;
|
||||
|
||||
return new Definition($places, $transitions);
|
||||
$placesMetadata = [];
|
||||
$placesMetadata['c'] = [
|
||||
'bg_color' => 'DeepSkyBlue',
|
||||
];
|
||||
|
||||
$transitionsMetadata = new \SplObjectStorage();
|
||||
$transitionsMetadata[$transitionWithMetadataDumpStyle] = [
|
||||
'label' => 'My custom transition label 2',
|
||||
'color' => 'Grey',
|
||||
'arrow_color' => 'Purple',
|
||||
];
|
||||
$transitionsMetadata[$transitionWithMetadataArrowColorPink] = [
|
||||
'arrow_color' => 'Pink',
|
||||
];
|
||||
$inMemoryMetadataStore = new InMemoryMetadataStore([], $placesMetadata, $transitionsMetadata);
|
||||
|
||||
return new Definition($places, $transitions, null, $inMemoryMetadataStore);
|
||||
|
||||
// The graph looks like:
|
||||
// +---+ +----+ +---+ +----+ +---+
|
||||
@ -82,13 +110,24 @@ trait WorkflowBuilderTrait
|
||||
$places = ['a', 'b', 'c', 'd'];
|
||||
|
||||
$transitions[] = new Transition('t1', 'a', 'b');
|
||||
$transitions[] = new Transition('t1', 'd', 'b');
|
||||
$transitions[] = new Transition('t2', 'b', 'c');
|
||||
$transitionWithMetadataDumpStyle = new Transition('t1', 'd', 'b');
|
||||
$transitions[] = $transitionWithMetadataDumpStyle;
|
||||
$transitionWithMetadataArrowColorBlue = new Transition('t2', 'b', 'c');
|
||||
$transitions[] = $transitionWithMetadataArrowColorBlue;
|
||||
$transitions[] = new Transition('t3', 'b', 'd');
|
||||
|
||||
$definition = new Definition($places, $transitions);
|
||||
$transitionsMetadata = new \SplObjectStorage();
|
||||
$transitionsMetadata[$transitionWithMetadataDumpStyle] = [
|
||||
'label' => 'My custom transition label 3',
|
||||
'color' => 'Grey',
|
||||
'arrow_color' => 'Red',
|
||||
];
|
||||
$transitionsMetadata[$transitionWithMetadataArrowColorBlue] = [
|
||||
'arrow_color' => 'Blue',
|
||||
];
|
||||
$inMemoryMetadataStore = new InMemoryMetadataStore([], [], $transitionsMetadata);
|
||||
|
||||
return $definition;
|
||||
return new Definition($places, $transitions, null, $inMemoryMetadataStore);
|
||||
|
||||
// The graph looks like:
|
||||
// t1
|
||||
|
@ -15,7 +15,7 @@ state "b"
|
||||
state "c" <<marked>>
|
||||
state "d"
|
||||
"a" --> "b": "t1"
|
||||
"d" --> "b": "t1"
|
||||
"b" --> "c": "t2"
|
||||
"d" -[#Red]-> "b": "<font color=Grey>My custom transition label 3</font>"
|
||||
"b" -[#Blue]-> "c": "t2"
|
||||
"b" --> "d": "t3"
|
||||
@enduml
|
||||
|
@ -15,7 +15,7 @@ state "b"
|
||||
state "c"
|
||||
state "d"
|
||||
"a" --> "b": "t1"
|
||||
"d" --> "b": "t1"
|
||||
"b" --> "c": "t2"
|
||||
"d" -[#Red]-> "b": "<font color=Grey>My custom transition label 3</font>"
|
||||
"b" -[#Blue]-> "c": "t2"
|
||||
"b" --> "d": "t3"
|
||||
@enduml
|
||||
|
@ -33,8 +33,8 @@ agent "t6"
|
||||
"b" --> "t2"
|
||||
"t2" --> "d"
|
||||
"c" --> "t2"
|
||||
"d" --> "t3"
|
||||
"t3" --> "e"
|
||||
"d" -[#Green]-> "t3": "<font color=Red>My custom transition label 1</font>"
|
||||
"t3" -[#Green]-> "e": "<font color=Red>My custom transition label 1</font>"
|
||||
"d" --> "t4"
|
||||
"t4" --> "f"
|
||||
"e" --> "t5"
|
||||
|
@ -33,8 +33,8 @@ agent "t6"
|
||||
"b" --> "t2"
|
||||
"t2" --> "d"
|
||||
"c" --> "t2"
|
||||
"d" --> "t3"
|
||||
"t3" --> "e"
|
||||
"d" -[#Green]-> "t3": "<font color=Red>My custom transition label 1</font>"
|
||||
"t3" -[#Green]-> "e": "<font color=Red>My custom transition label 1</font>"
|
||||
"d" --> "t4"
|
||||
"t4" --> "f"
|
||||
"e" --> "t5"
|
||||
|
@ -9,6 +9,7 @@ skinparam state {
|
||||
BorderColor #3887C6
|
||||
BorderColor<<marked>> Black
|
||||
FontColor<<marked>> White
|
||||
BackgroundColor<<DeepSkyBlue>> DeepSkyBlue
|
||||
}
|
||||
skinparam agent {
|
||||
BackgroundColor #ffffff
|
||||
@ -16,11 +17,11 @@ skinparam agent {
|
||||
}
|
||||
state "a" <<initial>>
|
||||
state "b" <<marked>>
|
||||
state "c"
|
||||
state "c" <<DeepSkyBlue>>
|
||||
agent "t1"
|
||||
agent "t2"
|
||||
"a" --> "t1"
|
||||
"t1" --> "b"
|
||||
"b" --> "t2"
|
||||
"t2" --> "c"
|
||||
"a" -[#Purple]-> "t1": "<font color=Grey>My custom transition label 2</font>"
|
||||
"t1" -[#Purple]-> "b": "<font color=Grey>My custom transition label 2</font>"
|
||||
"b" -[#Pink]-> "t2"
|
||||
"t2" -[#Pink]-> "c"
|
||||
@enduml
|
||||
|
@ -9,6 +9,7 @@ skinparam state {
|
||||
BorderColor #3887C6
|
||||
BorderColor<<marked>> Black
|
||||
FontColor<<marked>> White
|
||||
BackgroundColor<<DeepSkyBlue>> DeepSkyBlue
|
||||
}
|
||||
skinparam agent {
|
||||
BackgroundColor #ffffff
|
||||
@ -16,11 +17,11 @@ skinparam agent {
|
||||
}
|
||||
state "a" <<initial>>
|
||||
state "b"
|
||||
state "c"
|
||||
state "c" <<DeepSkyBlue>>
|
||||
agent "t1"
|
||||
agent "t2"
|
||||
"a" --> "t1"
|
||||
"t1" --> "b"
|
||||
"b" --> "t2"
|
||||
"t2" --> "c"
|
||||
"a" -[#Purple]-> "t1": "<font color=Grey>My custom transition label 2</font>"
|
||||
"t1" -[#Purple]-> "b": "<font color=Grey>My custom transition label 2</font>"
|
||||
"b" -[#Pink]-> "t2"
|
||||
"t2" -[#Pink]-> "c"
|
||||
@enduml
|
||||
|
Reference in New Issue
Block a user