mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-08-30 16:58:03 +08:00
Expand help text and add SVGs for apply rules, flat cross product, and nested cross product tools
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -27,28 +27,53 @@
|
||||
Synopsis
|
||||
========
|
||||
|
||||
This tool allows one to process an existing Galaxy dataset collection's metadata as tabular data,
|
||||
apply a series of rules to it, and generate a new collection.
|
||||
Reorganizes a collection by applying a chain of rules (filter, sort, rename, nest, flatten, tag) through an interactive rule builder.
|
||||
|
||||
===========
|
||||
Description
|
||||
===========
|
||||
|
||||
When used interactively in the tool form, a dynamic preview of the processing will be available in a tabular data viewer but this tool
|
||||
may be used in workflows as well where no such preview can be generated.
|
||||
This tool opens an interactive rule builder that lets you manipulate the element identifiers (and nesting structure) of a collection as if they were columns in a spreadsheet. You can chain multiple operations together — for example, split an identifier on a delimiter, use one part as a new nesting level and another as the element name, filter rows by a pattern, and sort the result — all in a single step.
|
||||
|
||||
This tool is an advanced feature but has a lot of flexibility - it can be used to process collections with arbitrary nesting and can do many kinds of filtering, re-sorting, nesting, flattening, and arbitrary combinations thereof not possible with Galaxy's other, more simple
|
||||
collection operation tools.
|
||||
This is an advanced tool that combines the capabilities of many simpler collection operations (sort, relabel, nest, flatten, filter) into one flexible interface. Use it when the simpler tools cannot achieve the reorganization you need.
|
||||
|
||||
More information about the rule processor in general can be found at `our training site`_.
|
||||
========
|
||||
Examples
|
||||
========
|
||||
|
||||
.. _our training site: https://training.galaxyproject.org/training-material/search?query=rule+builder
|
||||
**Flatten and re-nest by a different criterion**
|
||||
|
||||
-----
|
||||
Given a ``list:list`` collection where the outer identifiers are sequencing lanes and inner identifiers are sample names, you could use the rule builder to re-nest so that the outer level is sample name and the inner level is lane — effectively transposing the collection structure.
|
||||
|
||||
-------
|
||||
|
||||
**Extract metadata from identifiers**
|
||||
|
||||
If your element identifiers encode multiple pieces of information (e.g. ``patient01_treatment_rep2``), you can split on ``_`` to create columns, then use those columns to define new nesting levels, group tags, or filters.
|
||||
|
||||
-------
|
||||
|
||||
**Assign tags based on identifier patterns**
|
||||
|
||||
You can add a column derived from an identifier (e.g. extract "treatment" or "control" from the name) and assign it as a group tag, all within the rule builder.
|
||||
|
||||
-------
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/apply_rules.svg
|
||||
:alt: Apply rules to reorganize a collection
|
||||
:width: 500
|
||||
|
||||
-------
|
||||
|
||||
For detailed tutorials on the rule builder, visit `the Galaxy Training Network`_.
|
||||
|
||||
.. _the Galaxy Training Network: https://training.galaxyproject.org/training-material/search?query=rule+builder
|
||||
|
||||
-------
|
||||
|
||||
.. class:: infomark
|
||||
|
||||
@QUOTA_USAGE_NOTE@
|
||||
|
||||
]]></help>
|
||||
]]></help>
|
||||
</tool>
|
||||
|
||||
@@ -72,72 +72,72 @@
|
||||
Synopsis
|
||||
========
|
||||
|
||||
@CROSS_PRODUCT_INTRO@
|
||||
Creates two flat lists that, when processed element-wise by a downstream tool, produce every pairwise combination (all-vs-all) of the two input collections.
|
||||
|
||||
====================
|
||||
How to use this tool
|
||||
====================
|
||||
===========
|
||||
Description
|
||||
===========
|
||||
|
||||
@GALAXY_DOT_PRODUCT_SEMANTICS@
|
||||
This tool takes two list collections and produces two output lists that encode the **Cartesian product** (cross product) of the inputs. Both output lists have the same length (``n * m`` elements, where ``n`` and ``m`` are the sizes of the inputs) and the same element identifiers.
|
||||
|
||||
Running input lists through this tool produces new dataset lists (described in detail below) that when using
|
||||
the same natural element-wise matching "map over" semantics described above produce every combination of the
|
||||
elements of the two lists compared against each other. Running a tool with these two outputs instead of the initial
|
||||
two inputs produces a list of the comparison of each combination of pairs from the respective inputs.
|
||||
When you feed these two outputs into a tool that operates on pairs of datasets, Galaxy's element-wise matching ensures that every combination of one element from Input A and one element from Input B is compared exactly once.
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/flat_crossproduct_output.png
|
||||
:alt: The Flat Cartesian Product of Two Collections
|
||||
========
|
||||
Examples
|
||||
========
|
||||
|
||||
**All-vs-all comparison**
|
||||
|
||||
Given::
|
||||
|
||||
Input A: [a1] [a2]
|
||||
Input B: [b1] [b2]
|
||||
|
||||
The tool produces two flat lists of length 4::
|
||||
|
||||
Output A: [a1_b1 → a1] [a1_b2 → a1] [a2_b1 → a2] [a2_b2 → a2]
|
||||
Output B: [a1_b1 → b1] [a1_b2 → b2] [a2_b1 → b1] [a2_b2 → b2]
|
||||
|
||||
Feeding both outputs to a comparison tool produces::
|
||||
|
||||
Result: [a1_b1 → compare(a1,b1)]
|
||||
[a1_b2 → compare(a1,b2)]
|
||||
[a2_b1 → compare(a2,b1)]
|
||||
[a2_b2 → compare(a2,b2)]
|
||||
|
||||
The identifier separator (default ``_``) can be changed to ``:`` or ``-``.
|
||||
|
||||
-------
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/cross_product_flat.svg
|
||||
:alt: Flat cross product of two collections
|
||||
:width: 620
|
||||
|
||||
-------
|
||||
|
||||
==================================
|
||||
How element-wise matching works
|
||||
==================================
|
||||
|
||||
Normally, when you connect two lists to a tool that takes two inputs, Galaxy matches them element-wise (dot product): the first element of list 1 is paired with the first element of list 2, and so on. This requires both lists to have the same identifiers.
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/dot_product.png
|
||||
:alt: Element-wise (dot product) matching
|
||||
:width: 500
|
||||
|
||||
The result of running a subsequent tool with the outputs produced by this tool will be a much larger list
|
||||
whose element identifiers are the concatenation of the combinations of the elements identifiers from the
|
||||
two input lists.
|
||||
This tool rearranges the inputs so that the same element-wise matching mechanism produces every combination instead.
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/flat_crossproduct_separator.png
|
||||
:alt: Flat Cross Product Identifier Separator
|
||||
:width: 500
|
||||
-------
|
||||
|
||||
============================================
|
||||
What this tool does (technical details)
|
||||
============================================
|
||||
.. class:: infomark
|
||||
|
||||
This tool consumes two lists - we will call them ``input_a`` and ``input_b``. If ``input_a``
|
||||
has length ``n`` and dataset elements identified as ``a1``, ``a2``, ... ``an`` and ``input_b``
|
||||
has length ``m`` and dataset elements identified as ``b1``, ``b2``, ... ``bm``, then this tool
|
||||
produces a pair of larger lists - each of size ``n*m``.
|
||||
For a nested (``list:list``) output structure instead of a flat list, use **Nested Cross Product**.
|
||||
|
||||
Both output lists will be the same length and contain the same set of element identifiers in the
|
||||
same order. If the kth input can be described as ``(i-1)*n + (j-1)`` where ``1 <= i <= m`` and ``1 <= j <= n``
|
||||
then the element identifier for this kth element is the concatenation of the element identifier for
|
||||
the ith item of ``input_a`` and the jth item of ``input_b``.
|
||||
|
||||
In the first output list, this kth element will be the ith element of ``input_a``. In the second
|
||||
output list, the kth element will be the jth element of ``input_b``.
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/flat_cross_product_outputs.png
|
||||
:alt: Flat Cross Product Outputs
|
||||
:width: 500
|
||||
|
||||
These list structures might appear to be a little odd, but they have the very useful property
|
||||
that if you match up corresponding elements of the lists the result is each combination of
|
||||
elements in ``input_a`` and ``input_b`` are matched up once.
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/flat_cross_product_matched.png
|
||||
:alt: Flat Cross Product Matching Datasets
|
||||
:width: 500
|
||||
|
||||
Running a downstream comparison tool that compares two datasets with these two lists produces a
|
||||
new list with every combination of comparisons.
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/flat_cross_product_downstream.png
|
||||
:alt: Flat Cross Product All-vs-All Result
|
||||
:width: 500
|
||||
|
||||
----
|
||||
-------
|
||||
|
||||
.. class:: infomark
|
||||
|
||||
@QUOTA_USAGE_NOTE@
|
||||
|
||||
]]></help>
|
||||
]]></help>
|
||||
</tool>
|
||||
|
||||
@@ -76,75 +76,89 @@
|
||||
Synopsis
|
||||
========
|
||||
|
||||
@CROSS_PRODUCT_INTRO@
|
||||
Creates two nested lists (``list:list``) that, when processed element-wise by a downstream tool, produce every pairwise combination (all-vs-all) of the two input collections, organized by the first input.
|
||||
|
||||
====================
|
||||
How to use this tool
|
||||
====================
|
||||
===========
|
||||
Description
|
||||
===========
|
||||
|
||||
@GALAXY_DOT_PRODUCT_SEMANTICS@
|
||||
This tool takes two flat list collections and produces two ``list:list`` output collections that encode the **Cartesian product** (cross product) of the inputs. The outer list has one element per element of Input A, and each inner list has one element per element of Input B.
|
||||
|
||||
Running input lists through this tool produces new list structures (described in detail below) that when using
|
||||
the same natural element-wise matching "map over" semantics described above produce every combination of the
|
||||
elements of the two lists compared against each other. Running a tool with these two outputs instead of the initial
|
||||
two inputs produces a nested list structure where the jth element of the inner list of the ith element of the outer
|
||||
list is a comparison of the ith element of the first list to the jth element of the second list.
|
||||
Put more simply, the result is a nested list where the identifiers of an element describe which inputs were
|
||||
matched to produce the comparison output found at that element.
|
||||
When you feed these two outputs into a tool that takes two inputs, Galaxy matches elements at each nesting level. The result is a nested list where the outer identifier tells you which element from Input A was used, and the inner identifier tells you which element from Input B was used.
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/nested_crossproduct_output.png
|
||||
:alt: The Cartesian Product of Two Collections
|
||||
This is similar to **Flat Cross Product**, but the output preserves structure: results are grouped by the first input, making it easier to see all comparisons for a given element of Input A.
|
||||
|
||||
========
|
||||
Examples
|
||||
========
|
||||
|
||||
**All-vs-all comparison with nested output**
|
||||
|
||||
Given::
|
||||
|
||||
Input A: [a1] [a2]
|
||||
Input B: [b1] [b2]
|
||||
|
||||
The tool produces two ``list:list`` collections::
|
||||
|
||||
Output A (list:list):
|
||||
|
||||
a1/
|
||||
b1 → a1
|
||||
b2 → a1
|
||||
a2/
|
||||
b1 → a2
|
||||
b2 → a2
|
||||
|
||||
Output B (list:list):
|
||||
|
||||
a1/
|
||||
b1 → b1
|
||||
b2 → b2
|
||||
a2/
|
||||
b1 → b1
|
||||
b2 → b2
|
||||
|
||||
Feeding both outputs to a comparison tool produces::
|
||||
|
||||
Result (list:list):
|
||||
|
||||
a1/
|
||||
b1 → compare(a1, b1)
|
||||
b2 → compare(a1, b2)
|
||||
a2/
|
||||
b1 → compare(a2, b1)
|
||||
b2 → compare(a2, b2)
|
||||
|
||||
-------
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/cross_product_nested.svg
|
||||
:alt: Nested cross product of two collections
|
||||
:width: 620
|
||||
|
||||
-------
|
||||
|
||||
==================================
|
||||
How element-wise matching works
|
||||
==================================
|
||||
|
||||
Normally, when you connect two lists to a tool, Galaxy matches them element-wise (dot product). This tool rearranges the inputs so that the same matching mechanism produces every combination instead, with results grouped into a nested structure.
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/dot_product.png
|
||||
:alt: Element-wise (dot product) matching
|
||||
:width: 500
|
||||
|
||||
============================================
|
||||
What this tool does (technical details)
|
||||
============================================
|
||||
-------
|
||||
|
||||
This tool consumes two flat lists. We will call the input collections ``input_a`` and ``input_b``. If ``input_a``
|
||||
has length ``n`` and dataset elements identified as ``a1``, ``a2``, ... ``an`` and ``input_b``
|
||||
has length ``m`` and dataset elements identified as ``b1``, ``b2``, ... ``bm``, then this tool
|
||||
produces a pair of output nested lists (specifically of the ``list:list`` collection type) where
|
||||
the outer list is of length ``n`` and each inner list has a length of ``m`` (a ``n X m`` nested list). The jth element
|
||||
inside the outer list's ith element is a pseudo copy of the ith dataset of ``input_a``. One
|
||||
way to think about the output nested lists is as matrices. Here is a diagram of the first output
|
||||
showing the element identifiers of the outer and inner lists along with dataset identifiers being
|
||||
"copied" into this new collection.
|
||||
.. class:: infomark
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/nested_cross_product_out_1.png
|
||||
:alt: Nested Cross Product First Output
|
||||
:width: 500
|
||||
For a flat output list instead of nested, use **Flat Cross Product**.
|
||||
|
||||
The second output is a nested list of pseudo copies of the elements of ``input_b`` instead of
|
||||
``input_a``. In particular the outer list is again of length ``n`` and each inner list is again
|
||||
of length ``m`` but this time the jth element inside the outer list's ith element is a pseudo copy
|
||||
of the jth dataset of ``input_b``. Here is the matrix of these outputs.
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/nested_cross_product_out_2.png
|
||||
:alt: Nested Cross Product Second Output
|
||||
:width: 500
|
||||
|
||||
These nested list structures might appear to be a little odd, but they have the very useful property
|
||||
that if you match up corresponding elements of the nested lists the result is each combination of
|
||||
elements in ``input_a`` and ``input_b`` are matched up once. The following diagram describes these matching
|
||||
datasets.
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/nested_cross_product_matching.png
|
||||
:alt: Matching Inputs
|
||||
:width: 500
|
||||
|
||||
Running a tool that compares two datasets with these two nested lists produces a new nested list
|
||||
as described above. The following diagram shows the structure of this output and how the element
|
||||
identifiers are preserved and indicate what comparison was performed.
|
||||
|
||||
.. image:: ${static_path}/images/tools/collection_ops/nested_cross_product_output.png
|
||||
:alt: Matching Inputs
|
||||
:width: 500
|
||||
|
||||
----
|
||||
-------
|
||||
|
||||
.. class:: infomark
|
||||
|
||||
@QUOTA_USAGE_NOTE@
|
||||
|
||||
]]></help>
|
||||
]]></help>
|
||||
</tool>
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 620 200" width="620" height="200">
|
||||
<defs>
|
||||
<filter id="shadow" x="-4%" y="-4%" width="110%" height="110%">
|
||||
<feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blur"/>
|
||||
<feComponentTransfer in="blur">
|
||||
<feFuncA type="linear" slope="0.3"/>
|
||||
</feComponentTransfer>
|
||||
<feMerge>
|
||||
<feMergeNode/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#555"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Left: input collection -->
|
||||
<rect x="10" y="10" width="170" height="130" rx="8" ry="8" fill="#d9ead3" stroke="#888" stroke-width="1" filter="url(#shadow)"/>
|
||||
<text x="95" y="28" text-anchor="middle" font-family="sans-serif" font-size="12" font-weight="bold" fill="#333">List</text>
|
||||
|
||||
<rect x="22" y="38" width="146" height="26" rx="4" ry="4" fill="#fff" stroke="#aaa" stroke-width="0.7"/>
|
||||
<text x="95" y="56" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#333">patientA_treat_r1</text>
|
||||
|
||||
<rect x="22" y="70" width="146" height="26" rx="4" ry="4" fill="#fff" stroke="#aaa" stroke-width="0.7"/>
|
||||
<text x="95" y="88" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#333">patientA_ctrl_r1</text>
|
||||
|
||||
<rect x="22" y="102" width="146" height="26" rx="4" ry="4" fill="#fff" stroke="#aaa" stroke-width="0.7"/>
|
||||
<text x="95" y="120" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#333">patientB_treat_r1</text>
|
||||
|
||||
<!-- Rules box -->
|
||||
<rect x="40" y="153" width="110" height="35" rx="6" ry="6" fill="#e8d5f5" stroke="#7b4fa0" stroke-width="1"/>
|
||||
<text x="95" y="175" text-anchor="middle" font-family="sans-serif" font-size="10" font-weight="bold" fill="#7b4fa0">Rule Builder</text>
|
||||
|
||||
<!-- Arrow -->
|
||||
<line x1="195" y1="80" x2="355" y2="80" stroke="#555" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||||
<text x="275" y="70" text-anchor="middle" font-family="sans-serif" font-size="12" font-weight="bold" fill="#555">Apply rules</text>
|
||||
<text x="275" y="98" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#888">split, nest, tag</text>
|
||||
|
||||
<!-- Right: reorganized nested collection -->
|
||||
<rect x="370" y="10" width="240" height="180" rx="8" ry="8" fill="#d9ead3" stroke="#888" stroke-width="1" filter="url(#shadow)"/>
|
||||
<text x="490" y="28" text-anchor="middle" font-family="sans-serif" font-size="12" font-weight="bold" fill="#333">Nested list (re-organized)</text>
|
||||
|
||||
<!-- Inner: patientA -->
|
||||
<rect x="382" y="38" width="216" height="62" rx="6" ry="6" fill="#e8f0e3" stroke="#aaa" stroke-width="0.7"/>
|
||||
<text x="410" y="53" font-family="sans-serif" font-size="10" font-weight="bold" fill="#555">patientA</text>
|
||||
|
||||
<rect x="394" y="58" width="192" height="16" rx="3" ry="3" fill="#fff" stroke="#aaa" stroke-width="0.5"/>
|
||||
<text x="490" y="70" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#333">treat_r1</text>
|
||||
|
||||
<rect x="394" y="78" width="192" height="16" rx="3" ry="3" fill="#fff" stroke="#aaa" stroke-width="0.5"/>
|
||||
<text x="490" y="90" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#333">ctrl_r1</text>
|
||||
|
||||
<!-- Inner: patientB -->
|
||||
<rect x="382" y="108" width="216" height="50" rx="6" ry="6" fill="#e8f0e3" stroke="#aaa" stroke-width="0.7"/>
|
||||
<text x="410" y="123" font-family="sans-serif" font-size="10" font-weight="bold" fill="#555">patientB</text>
|
||||
|
||||
<rect x="394" y="128" width="192" height="16" rx="3" ry="3" fill="#fff" stroke="#aaa" stroke-width="0.5"/>
|
||||
<text x="490" y="140" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#333">treat_r1</text>
|
||||
|
||||
<text x="490" y="178" text-anchor="middle" font-family="sans-serif" font-size="10" font-style="italic" fill="#666">split on "_", nest by patient</text>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 680 310" width="680" height="310">
|
||||
<defs>
|
||||
<filter id="shadow" x="-4%" y="-4%" width="110%" height="110%">
|
||||
<feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blur"/>
|
||||
<feComponentTransfer in="blur">
|
||||
<feFuncA type="linear" slope="0.3"/>
|
||||
</feComponentTransfer>
|
||||
<feMerge>
|
||||
<feMergeNode/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#555"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Input A -->
|
||||
<rect x="10" y="10" width="150" height="90" rx="8" ry="8" fill="#fef3e2" stroke="#d4760a" stroke-width="1" filter="url(#shadow)"/>
|
||||
<text x="85" y="28" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="bold" fill="#d4760a">Input A</text>
|
||||
|
||||
<rect x="22" y="36" width="126" height="22" rx="4" ry="4" fill="#fff" stroke="#d4760a" stroke-width="0.5"/>
|
||||
<text x="85" y="51" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#d4760a">a1</text>
|
||||
|
||||
<rect x="22" y="64" width="126" height="22" rx="4" ry="4" fill="#fff" stroke="#d4760a" stroke-width="0.5"/>
|
||||
<text x="85" y="79" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#d4760a">a2</text>
|
||||
|
||||
<!-- Input B -->
|
||||
<rect x="10" y="120" width="150" height="90" rx="8" ry="8" fill="#f0e8f5" stroke="#7b4fa0" stroke-width="1" filter="url(#shadow)"/>
|
||||
<text x="85" y="138" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="bold" fill="#7b4fa0">Input B</text>
|
||||
|
||||
<rect x="22" y="146" width="126" height="22" rx="4" ry="4" fill="#fff" stroke="#7b4fa0" stroke-width="0.5"/>
|
||||
<text x="85" y="161" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#7b4fa0">b1</text>
|
||||
|
||||
<rect x="22" y="174" width="126" height="22" rx="4" ry="4" fill="#fff" stroke="#7b4fa0" stroke-width="0.5"/>
|
||||
<text x="85" y="189" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#7b4fa0">b2</text>
|
||||
|
||||
<!-- Arrow -->
|
||||
<line x1="175" y1="130" x2="310" y2="130" stroke="#555" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||||
<text x="243" y="120" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="bold" fill="#555">Cross</text>
|
||||
<text x="243" y="148" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#888">product</text>
|
||||
|
||||
<!-- Output A (flat) -->
|
||||
<rect x="325" y="10" width="170" height="140" rx="8" ry="8" fill="#fef3e2" stroke="#d4760a" stroke-width="1" filter="url(#shadow)"/>
|
||||
<text x="410" y="28" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="bold" fill="#d4760a">Output A</text>
|
||||
|
||||
<rect x="337" y="36" width="146" height="20" rx="4" ry="4" fill="#fff" stroke="#d4760a" stroke-width="0.5"/>
|
||||
<text x="410" y="50" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#333">a1_b1 → a1</text>
|
||||
|
||||
<rect x="337" y="62" width="146" height="20" rx="4" ry="4" fill="#fff" stroke="#d4760a" stroke-width="0.5"/>
|
||||
<text x="410" y="76" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#333">a1_b2 → a1</text>
|
||||
|
||||
<rect x="337" y="88" width="146" height="20" rx="4" ry="4" fill="#fff" stroke="#d4760a" stroke-width="0.5"/>
|
||||
<text x="410" y="102" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#333">a2_b1 → a2</text>
|
||||
|
||||
<rect x="337" y="114" width="146" height="20" rx="4" ry="4" fill="#fff" stroke="#d4760a" stroke-width="0.5"/>
|
||||
<text x="410" y="128" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#333">a2_b2 → a2</text>
|
||||
|
||||
<!-- Output B (flat) -->
|
||||
<rect x="325" y="165" width="170" height="140" rx="8" ry="8" fill="#f0e8f5" stroke="#7b4fa0" stroke-width="1" filter="url(#shadow)"/>
|
||||
<text x="410" y="183" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="bold" fill="#7b4fa0">Output B</text>
|
||||
|
||||
<rect x="337" y="191" width="146" height="20" rx="4" ry="4" fill="#fff" stroke="#7b4fa0" stroke-width="0.5"/>
|
||||
<text x="410" y="205" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#333">a1_b1 → b1</text>
|
||||
|
||||
<rect x="337" y="217" width="146" height="20" rx="4" ry="4" fill="#fff" stroke="#7b4fa0" stroke-width="0.5"/>
|
||||
<text x="410" y="231" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#333">a1_b2 → b2</text>
|
||||
|
||||
<rect x="337" y="243" width="146" height="20" rx="4" ry="4" fill="#fff" stroke="#7b4fa0" stroke-width="0.5"/>
|
||||
<text x="410" y="257" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#333">a2_b1 → b1</text>
|
||||
|
||||
<rect x="337" y="269" width="146" height="20" rx="4" ry="4" fill="#fff" stroke="#7b4fa0" stroke-width="0.5"/>
|
||||
<text x="410" y="283" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#333">a2_b2 → b2</text>
|
||||
|
||||
<!-- Annotation -->
|
||||
<text x="580" y="80" text-anchor="middle" font-family="sans-serif" font-size="10" font-style="italic" fill="#666">Match element-wise</text>
|
||||
<text x="580" y="95" text-anchor="middle" font-family="sans-serif" font-size="10" font-style="italic" fill="#666">to get all-vs-all</text>
|
||||
|
||||
<!-- Brace-like connector -->
|
||||
<line x1="500" y1="75" x2="530" y2="75" stroke="#aaa" stroke-width="1"/>
|
||||
<line x1="500" y1="230" x2="530" y2="230" stroke="#aaa" stroke-width="1"/>
|
||||
<line x1="530" y1="75" x2="530" y2="230" stroke="#aaa" stroke-width="1"/>
|
||||
<line x1="530" y1="152" x2="545" y2="152" stroke="#aaa" stroke-width="1"/>
|
||||
|
||||
<text x="580" y="140" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#888">a1_b1: compare(a1,b1)</text>
|
||||
<text x="580" y="153" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#888">a1_b2: compare(a1,b2)</text>
|
||||
<text x="580" y="166" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#888">a2_b1: compare(a2,b1)</text>
|
||||
<text x="580" y="179" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#888">a2_b2: compare(a2,b2)</text>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 680 320" width="680" height="320">
|
||||
<defs>
|
||||
<filter id="shadow" x="-4%" y="-4%" width="110%" height="110%">
|
||||
<feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blur"/>
|
||||
<feComponentTransfer in="blur">
|
||||
<feFuncA type="linear" slope="0.3"/>
|
||||
</feComponentTransfer>
|
||||
<feMerge>
|
||||
<feMergeNode/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#555"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Input A -->
|
||||
<rect x="10" y="10" width="150" height="90" rx="8" ry="8" fill="#fef3e2" stroke="#d4760a" stroke-width="1" filter="url(#shadow)"/>
|
||||
<text x="85" y="28" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="bold" fill="#d4760a">Input A</text>
|
||||
|
||||
<rect x="22" y="36" width="126" height="22" rx="4" ry="4" fill="#fff" stroke="#d4760a" stroke-width="0.5"/>
|
||||
<text x="85" y="51" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#d4760a">a1</text>
|
||||
|
||||
<rect x="22" y="64" width="126" height="22" rx="4" ry="4" fill="#fff" stroke="#d4760a" stroke-width="0.5"/>
|
||||
<text x="85" y="79" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#d4760a">a2</text>
|
||||
|
||||
<!-- Input B -->
|
||||
<rect x="10" y="120" width="150" height="90" rx="8" ry="8" fill="#f0e8f5" stroke="#7b4fa0" stroke-width="1" filter="url(#shadow)"/>
|
||||
<text x="85" y="138" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="bold" fill="#7b4fa0">Input B</text>
|
||||
|
||||
<rect x="22" y="146" width="126" height="22" rx="4" ry="4" fill="#fff" stroke="#7b4fa0" stroke-width="0.5"/>
|
||||
<text x="85" y="161" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#7b4fa0">b1</text>
|
||||
|
||||
<rect x="22" y="174" width="126" height="22" rx="4" ry="4" fill="#fff" stroke="#7b4fa0" stroke-width="0.5"/>
|
||||
<text x="85" y="189" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#7b4fa0">b2</text>
|
||||
|
||||
<!-- Arrow -->
|
||||
<line x1="175" y1="130" x2="310" y2="130" stroke="#555" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||||
<text x="243" y="120" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="bold" fill="#555">Cross</text>
|
||||
<text x="243" y="148" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#888">product</text>
|
||||
|
||||
<!-- Output A (nested list:list) -->
|
||||
<rect x="325" y="10" width="170" height="140" rx="8" ry="8" fill="#fef3e2" stroke="#d4760a" stroke-width="1" filter="url(#shadow)"/>
|
||||
<text x="410" y="28" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="bold" fill="#d4760a">Output A (list:list)</text>
|
||||
|
||||
<!-- Inner: a1 -->
|
||||
<rect x="337" y="36" width="146" height="44" rx="5" ry="5" fill="#fff6e8" stroke="#d4760a" stroke-width="0.5"/>
|
||||
<text x="352" y="49" font-family="sans-serif" font-size="9" font-weight="bold" fill="#d4760a">a1</text>
|
||||
|
||||
<rect x="349" y="53" width="122" height="14" rx="3" ry="3" fill="#fff" stroke="#d4760a" stroke-width="0.4"/>
|
||||
<text x="410" y="63" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#333">b1 → a1</text>
|
||||
|
||||
<rect x="349" y="69" width="122" height="14" rx="3" ry="3" fill="#fff" stroke="#d4760a" stroke-width="0.4"/>
|
||||
<text x="410" y="79" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#333">b2 → a1</text>
|
||||
|
||||
<!-- Inner: a2 -->
|
||||
<rect x="337" y="86" width="146" height="44" rx="5" ry="5" fill="#fff6e8" stroke="#d4760a" stroke-width="0.5"/>
|
||||
<text x="352" y="99" font-family="sans-serif" font-size="9" font-weight="bold" fill="#d4760a">a2</text>
|
||||
|
||||
<rect x="349" y="103" width="122" height="14" rx="3" ry="3" fill="#fff" stroke="#d4760a" stroke-width="0.4"/>
|
||||
<text x="410" y="113" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#333">b1 → a2</text>
|
||||
|
||||
<rect x="349" y="119" width="122" height="14" rx="3" ry="3" fill="#fff" stroke="#d4760a" stroke-width="0.4"/>
|
||||
<text x="410" y="129" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#333">b2 → a2</text>
|
||||
|
||||
<!-- Output B (nested list:list) -->
|
||||
<rect x="325" y="165" width="170" height="140" rx="8" ry="8" fill="#f0e8f5" stroke="#7b4fa0" stroke-width="1" filter="url(#shadow)"/>
|
||||
<text x="410" y="183" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="bold" fill="#7b4fa0">Output B (list:list)</text>
|
||||
|
||||
<!-- Inner: a1 -->
|
||||
<rect x="337" y="191" width="146" height="44" rx="5" ry="5" fill="#f5eefa" stroke="#7b4fa0" stroke-width="0.5"/>
|
||||
<text x="352" y="204" font-family="sans-serif" font-size="9" font-weight="bold" fill="#7b4fa0">a1</text>
|
||||
|
||||
<rect x="349" y="208" width="122" height="14" rx="3" ry="3" fill="#fff" stroke="#7b4fa0" stroke-width="0.4"/>
|
||||
<text x="410" y="218" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#333">b1 → b1</text>
|
||||
|
||||
<rect x="349" y="224" width="122" height="14" rx="3" ry="3" fill="#fff" stroke="#7b4fa0" stroke-width="0.4"/>
|
||||
<text x="410" y="234" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#333">b2 → b2</text>
|
||||
|
||||
<!-- Inner: a2 -->
|
||||
<rect x="337" y="241" width="146" height="44" rx="5" ry="5" fill="#f5eefa" stroke="#7b4fa0" stroke-width="0.5"/>
|
||||
<text x="352" y="254" font-family="sans-serif" font-size="9" font-weight="bold" fill="#7b4fa0">a2</text>
|
||||
|
||||
<rect x="349" y="258" width="122" height="14" rx="3" ry="3" fill="#fff" stroke="#7b4fa0" stroke-width="0.4"/>
|
||||
<text x="410" y="268" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#333">b1 → b1</text>
|
||||
|
||||
<rect x="349" y="274" width="122" height="14" rx="3" ry="3" fill="#fff" stroke="#7b4fa0" stroke-width="0.4"/>
|
||||
<text x="410" y="284" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#333">b2 → b2</text>
|
||||
|
||||
<!-- Annotation -->
|
||||
<text x="580" y="75" text-anchor="middle" font-family="sans-serif" font-size="10" font-style="italic" fill="#666">Results grouped</text>
|
||||
<text x="580" y="90" text-anchor="middle" font-family="sans-serif" font-size="10" font-style="italic" fill="#666">by Input A element</text>
|
||||
|
||||
<!-- Result annotation -->
|
||||
<text x="580" y="150" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#888">a1/b1: compare(a1,b1)</text>
|
||||
<text x="580" y="163" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#888">a1/b2: compare(a1,b2)</text>
|
||||
<text x="580" y="176" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#888">a2/b1: compare(a2,b1)</text>
|
||||
<text x="580" y="189" text-anchor="middle" font-family="sans-serif" font-size="9" fill="#888">a2/b2: compare(a2,b2)</text>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.6 KiB |
Reference in New Issue
Block a user