Buffers/products example

This example shows:

  • Improving hierarchical scalability by making use of the reuse of mappings.
  • Improving hierarchical scalability by making copies of copied elements.

It is assumed the reader is already familiar with the workstation example.

SVG image

The following SVG image is used for this example:


The SVG image contains a single template for a buffer (large rectangle), with one product (small rectangle). The template is moved outside of the canvas to ensure the template itself is not shown.

The SVG file has the following XML content:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns=""
     width="220" height="70" id="root" version="1.1">
  <g id="buffer">
    <rect width="100" height="50" x="-120" y="10" id="background" style="fill:#ff0000"/>
    <rect width="10"  height="30" x="-110" y="20" id="product"    style="fill:#8b0000;visibility:hidden;"/>

We’ll use CIF to turn this into two buffers with three products each, in a scalable manner. That is, to add a single buffer, we only need one more instantiation, and also to put an additional product in each buffer, we also only need one more instantiation.

CIF specification

The following CIF specification models the buffers/products example:

svgfile "buffers_products.svg";

buffer0: Buffer(0);
buffer1: Buffer(1);

group def Buffer(alg int nr):
  svgcopy id "buffer" post <string>nr;

  svgmove id "buffer" + <string>nr to 10 + nr * 110, 10;

  product0: Product(nr, 0);
  product1: Product(nr, 1);
  product2: Product(nr, 2);

group def Product(alg int bufferNr, productNr):
  svgcopy id "product" + <string>bufferNr post "_" + <string>productNr;

  svgout id fmt("product%d_%d", bufferNr, productNr)
         attr "transform"
         value fmt("translate(%d,0)", productNr * 20);

  svgout id fmt("product%d_%d", bufferNr, productNr)
         attr "visibility"
         value "visible";

Two buffers are present (buffer0 and buffer1). Both are instances of the Buffer definition, and are provided with their own identity (parameter nr). For each buffer, the buffer element of the image is copied, and the copy is given a unique number. For instance, for instantiation buffer0, nr is 0, and thus buffer is copied to buffer0, background is copied to background0 and product is copied to product0.

Each buffer is also moved. The first buffer (nr 0) gets moved to position (10, 10), while the second (nr 1) gets moved to position (120, 10).

Each buffer contains three products, as the Product definition is instantiated three times. The number of the buffer is passed along, as is a unique product number. For the copy of the products, the copy of the product in the copied buffer is copied, and given a unique name using the product number. For buffer0, the copy of the product was already named product0. This already copied element is copied another three times, to product0_0 (by the copy declaration in CIF group buffer0.product0), product0_1 (by the copy declaration in CIF group buffer0.product1), and product0_2 (by the copy declaration in CIF group buffer0.product2). Similarly, three copies are made for buffer1.

Unlike the buffers, which are moved to an absolute position using an svgmove, the products are moved relatively, using an svgout for their transform attribute. The first product (product0_0) is not moved, the second product (product0_1) is moved 20 pixels, etc.

The buffer template was put outside of the canvas to show only the copies and not the template. For the products, which are contained in the buffers, this trick is not possible. So, instead the visibility of the template product was set to hidden in the original SVG image. To show the actual (copied) products, an svgout is used to set the visibility attribute to visible. The template product is not changed, so it remains hidden.

The result of all this hierarchical 2-level structure is the following SVG image: