# Charts and Barcodes

> Add QR codes and barcodes with TXBarcodeCore and BarcodeFrame, find, remove and export them as SVG, and insert ChartFrame charts bound to data on Windows.

- **Product:** TX Text Control .NET Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET Server > Document Processing > Charts and Barcodes
- **6224 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/charts-barcodes/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/charts-barcodes/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/charts-barcodes/llms-full.txt

---

A QR code that opens an invoice online, a Code 128 barcode with an order number on a packing slip and a chart in a quarterly report are frames that TX Text Control places in a document like images. On the server, your code creates barcodes, styles them, puts them into headers, finds and removes the barcodes of loaded documents and exports a barcode as an SVG image. Charts come with their own requirement, which the last section describes.

Barcodes that a mail merge fills with data, including the table of barcode types and the check of values before merging, are the subject of [Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/barcodes/llms-full.txt) in Mail Merge and Reporting. Frames are placed as described in [Images](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/images/#how-images-are-placed).

### How Barcodes Work

A barcode in a document consists of two objects:

- **[TXBarcodeCore](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/llms-full.txt)** holds the barcode itself: its [BarcodeType](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/barcodetype/enumeration/llms-full.txt), the encoded text and its appearance. It renders the barcode as SVG and must be initialized with [Create](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/create-method/llms-full.txt) before it's used. The Core engine creates barcodes with this class.
- **[BarcodeFrame](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/barcodeframe/llms-full.txt)** places the barcode in the document, with a name, an ID, a size and a position, like an image or a text frame.

[ServerTextControl.Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/barcodes-property/llms-full.txt) returns the [BarcodeCollection](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/barcodecollection/llms-full.txt) of the main text, and headers, footers and text frames have their own, such as [HeaderFooter.Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/headerfooter/barcodes-property/llms-full.txt).

Barcodes are saved as barcodes in the TX Text Control format and RTF. Other formats, such as DOCX and PDF, contain an image of the barcode.

A document can combine both kinds of codes. The packing slip of the blog article [Enhancing Documents with QR Codes and Barcodes in .NET C#: A Comprehensive Guide](https://www.textcontrol.com/blog/2024/07/11/enhancing-documents-with-qr-codes-and-barcodes-in-net-csharp-a-comprehensive-guide/), created by a mail merge, has a QR code in its top-right corner and a one-dimensional barcode with the item code in each row of its item table:

![A packing slip created with TX Text Control: a QR code next to the heading and, in the item table, one barcode with its encoded digits per row.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-server/packing-slip-barcodes.4a025714.webp)

### Insert a QR Code and a Barcode

The following program writes the heading of an invoice, anchors a dark blue QR code with a link at the right edge and inserts a Code 128 barcode with the invoice number inline with the text:

```csharp
using System.Drawing;
using TXTextControl;
using TXTextControl.Barcode;
using TXTextControl.DataVisualization;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();
    tx.Text = "Invoice INV-2025-001\r\nScan the code to open the invoice in the customer portal.\r\n";

    const string portalLink = "https://www.textcontrol.com";

    TXBarcodeCore qrCode = new TXBarcodeCore();
    qrCode.Create();
    qrCode.BarcodeType = BarcodeType.QRCode;
    qrCode.UpperTextLength = portalLink.Length;
    qrCode.Text = portalLink;
    qrCode.ForeColor = Color.DarkBlue;

    BarcodeFrame qrFrame = new BarcodeFrame(qrCode)
    {
        Name = "portal-link",
        Size = new Size(1440, 1440) // 1 x 1 inch in twips
    };

    // Anchored to the paragraph at the input position, the text flows around it
    tx.Barcodes.Add(qrFrame, HorizontalAlignment.Right, -1, FrameInsertionMode.DisplaceText);

    TXBarcodeCore invoiceCode = new TXBarcodeCore();
    invoiceCode.Create();
    invoiceCode.BarcodeType = BarcodeType.Code128;
    invoiceCode.UpperTextLength = 12;
    invoiceCode.Text = "INV-2025-001";
    invoiceCode.ShowText = true;
    invoiceCode.AdditionalText = "Invoice number";
    invoiceCode.TextAlignment = TextAlignment.Bottom;

    // Inline, like a single character, at the input position
    tx.Barcodes.Add(new BarcodeFrame(invoiceCode) { Size = new Size(4320, 1080) }, -1);

    tx.Save("barcodes.pdf", StreamType.AdobePDF);
}
```

The code works as follows:

- [UpperTextLength](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/uppertextlength-property/llms-full.txt) is the maximum number of characters, and [Text](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/text-property/llms-full.txt) the encoded text. Both throw an `ArgumentException` when the value isn't valid for the barcode type, so the type is set first.
- [ForeColor](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/forecolor-property/llms-full.txt) and [BackColor](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/backcolor-property/llms-full.txt) are the colors of the code and its background, and [Angle](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/angle-property/llms-full.txt) rotates it.
- [ShowText](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/showtext-property/llms-full.txt) shows the encoded text of a one-dimensional barcode, and [AdditionalText](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/additionaltext-property/llms-full.txt) adds a text of your own. [TextAlignment](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/textalignment-property/llms-full.txt) puts both texts at the `Bottom` or the `Top`.
- [BarcodeCollection.Add](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/barcodecollection/add-method/llms-full.txt) with an alignment anchors the barcode to the paragraph that contains the text position. For the [FrameInsertionMode](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/frameinsertionmode/enumeration/llms-full.txt), `DisplaceText`, `DisplaceCompleteLines`, `AboveTheText` and `BelowTheText` can be used. `Add(frame, -1)` inserts the barcode inline.

[Alignment](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/alignment-property/llms-full.txt) positions the code inside its frame, `MiddleCenter` by default. [BarcodeTypeSettings](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/barcodetypesettings-property/llms-full.txt) controls the check value of the types that have one: [HasCheckValue](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/barcodetypesettings/hascheckvalue-property/llms-full.txt) adds it, and [ShowCheckValue](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/barcodetypesettings/showcheckvalue-property/llms-full.txt) shows it with the text.

### Put a QR Code Into the Header

A barcode in the header appears on every page of its section. The following program adds a header and anchors a QR code with the invoice number at its right edge:

```csharp
using System.Drawing;
using TXTextControl;
using TXTextControl.Barcode;
using TXTextControl.DataVisualization;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();
    tx.Text = "Invoice INV-2025-001";

    TXBarcodeCore qrCode = new TXBarcodeCore();
    qrCode.Create();
    qrCode.BarcodeType = BarcodeType.QRCode;
    qrCode.UpperTextLength = 12;
    qrCode.Text = "INV-2025-001";

    tx.HeadersAndFooters.Add(HeaderFooterType.Header);
    HeaderFooter header = tx.HeadersAndFooters.GetItem(HeaderFooterType.Header);

    // Shown on every page of the section
    header.Barcodes.Add(new BarcodeFrame(qrCode) { Size = new Size(1080, 1080) },
        HorizontalAlignment.Right, -1, FrameInsertionMode.AboveTheText);

    tx.Save("header-qr-code.pdf", StreamType.AdobePDF);
}
```

To place a barcode on a single page instead, use the overload with a page number and a location: `tx.Barcodes.Add(frame, 1, new Point(8640, 720), FrameInsertionMode.AboveTheText)` places it on page 1, relative to the top-left corner of the page. The blog article [Using QR Codes in PDF Documents in C# .NET](https://www.textcontrol.com/blog/2026/04/21/using-qr-codes-in-pdf-documents-in-csharp-dotnet/) shows further uses of QR codes.

### Find and Remove the Barcodes of a Document

The following program lists the barcodes of a document saved in the TX Text Control format and removes the barcode named "portal-link":

```csharp
using TXTextControl;
using TXTextControl.DataVisualization;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();

    // Occurs for each barcode of the loaded document
    tx.BarcodeCreated += (sender, e) => Console.WriteLine($"Loaded barcode '{e.BarcodeFrame.Name}'");

    tx.Load("Documents/barcodes.tx", StreamType.InternalUnicodeFormat);

    foreach (BarcodeFrame frame in tx.Barcodes)
    {
        Console.WriteLine($"'{frame.Name}': {frame.Size.Width} x {frame.Size.Height} twips, text position {frame.TextPosition}");
    }

    // null if no barcode has this name
    BarcodeFrame portal = tx.Barcodes.GetItem("portal-link");

    if (portal != null)
    {
        tx.Barcodes.Remove(portal);
    }

    tx.Save("barcodes-changed.tx", StreamType.InternalUnicodeFormat);
}
```

The code works as follows:

- [BarcodeCreated](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/barcodecreated-event/llms-full.txt) occurs for each barcode of a loaded document, but not for barcodes added with `Add`. [BarcodeDeleted](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/barcodedeleted-event/llms-full.txt) occurs when a barcode is removed with `Remove`.
- [BarcodeCollection.GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/barcodecollection/getitem-method/llms-full.txt) returns a barcode by its name or ID, or `null`, and [Remove](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/barcodecollection/remove-method/llms-full.txt) removes it.

[BarcodeFrame.Barcode](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/barcodeframe/barcode-property/llms-full.txt) returns the barcode object of a frame. Changes to the barcode aren't shown automatically: call [Refresh](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/barcodeframe/refresh-method/llms-full.txt) of the frame after changing it.

### Export a Barcode as SVG

A barcode can also be created without a document, for example for a web page or an email. [GetSVG](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/getsvg-method/llms-full.txt) returns the barcode as an SVG string:

```csharp
using System.Drawing;
using TXTextControl.Barcode;

const string portalLink = "https://www.textcontrol.com";

TXBarcodeCore qrCode = new TXBarcodeCore();
qrCode.Create();
qrCode.BarcodeType = BarcodeType.QRCode;
qrCode.UpperTextLength = portalLink.Length;
qrCode.Text = portalLink;

// The size also sets TXBarcodeCore.Size
string svg = qrCode.GetSVG(new Size(5000, 5000));
File.WriteAllText("qrcode.svg", svg);
```

Before you set `Text` from user input, the static [IsTextValid](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/istextvalid-method/llms-full.txt) checks whether a text is valid for a barcode type, as [Check Values Before Merging](https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/barcodes/#check-values-before-merging) shows. [GetDefaultText](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/getdefaulttext-method/llms-full.txt) returns a valid sample text for a type, and the static [GetMinimumTextLength](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/getminimumtextlength-method/llms-full.txt) and [GetMaximumTextLength](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/getmaximumtextlength-method/llms-full.txt) return the shortest and longest text it takes, for example to set `UpperTextLength`.

To keep a barcode's settings apart from a document, [Save](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/save-method/llms-full.txt) writes the barcode data to a file, a `Stream`, a `TextWriter` or an `XmlWriter`, and [Load](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/load-method/llms-full.txt) reads it into a `TXBarcodeCore` again. [ViewChanged](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-barcode/txbarcodecore/viewchanged-event/llms-full.txt) occurs when a change of the settings requires the barcode to be drawn again.

```csharp
// Save the settings of the QR code and load them into a new object
qrCode.Save("qrcode-settings.xml");

TXBarcodeCore copy = new TXBarcodeCore();
copy.Create();
copy.Load("qrcode-settings.xml");
```

### Charts

A chart in a document is a [ChartFrame](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/chartframe/llms-full.txt). The frame places the chart like a barcode, while the chart itself is a chart control of the type `System.Windows.Forms.DataVisualization.Charting.Chart`, which holds its appearance and data. Charts can only be used where the assembly with this class is available. This chart control of the .NET Framework wasn't ported to .NET; the blog article [Using Charts with TX Text Control .NET for Windows 31.0 in .NET 6](https://www.textcontrol.com/blog/2022/11/02/using-charts-with-tx-text-control-net-for-windows-3100-in-net-6/) describes a fork that makes it available in .NET 6 Windows Forms applications.

The chart controls offer more than 30 diagram types, such as bars, pies, donuts and financial series.

#### Insert a Chart

The following program needs a Windows project that references `System.Windows.Forms.DataVisualization`, from the .NET Framework or from the fork the blog article above describes. It binds a bar chart to the XML data below and inserts it at the input position:

```xml
<?xml version="1.0" encoding="utf-8" ?>
<sales>
  <points>
    <country>Country 1</country>
    <value>100</value>
  </points>
  <points>
    <country>Country 2</country>
    <value>120</value>
  </points>
</sales>
```

Save the data as *Documents/sales.xml*. The program:

```csharp
using System.Data;
using System.Windows.Forms.DataVisualization.Charting;
using TXTextControl;
using TXTextControl.DataVisualization;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();
    tx.Selection.Text = "Sales by country:\r\n";

    // The chart control of the .NET Framework holds the appearance and the data
    Chart chart = new Chart();
    chart.ChartAreas.Add("chartArea1");
    chart.Series.Add("series1");
    chart.Series["series1"].ChartArea = "chartArea1";
    chart.Series["series1"].ChartType = SeriesChartType.Bar;

    DataSet data = new DataSet();
    data.ReadXml("Documents/sales.xml");

    chart.Series[0].XValueMember = data.Tables[0].Columns[0].ColumnName;
    chart.Series[0].YValueMembers = data.Tables[0].Columns[1].ColumnName;
    chart.DataSource = data.Tables[0];
    chart.DataBind();

    // The frame places the chart in the document
    ChartFrame frame = new ChartFrame(chart)
    {
        Name = "sales"
    };

    // Inline at the input position
    tx.Charts.Add(frame, -1);

    tx.Save("sales.tx", StreamType.InternalUnicodeFormat);
}
```

The [ChartFrame constructor](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/chartframe/constructor/llms-full.txt) takes the `Chart` control, which [ChartFrame.Chart](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/chartframe/chart-property/llms-full.txt) returns later. [ChartCollection.Add](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/chartcollection/add-method/llms-full.txt) has the same overloads as `BarcodeCollection.Add`: inline, anchored to a paragraph with an alignment or a location, and at a fixed position on a page or in the document.

#### What Else to Know About Charts

- **Collections and events.** [ServerTextControl.Charts](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/charts-property/llms-full.txt) returns the [ChartCollection](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/chartcollection/llms-full.txt) of the main text, with `Add`, `GetItem` and `Remove` as for barcodes. [ChartCreated](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/chartcreated-event/llms-full.txt) occurs for each chart of a loaded document, and [ChartDeleted](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/chartdeleted-event/llms-full.txt) when a chart is removed. After changing a chart, call [ChartFrame.Refresh](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-datavisualization/chartframe/refresh-method/llms-full.txt).
- **Formats.** Charts are saved as charts in the TX Text Control format and RTF, and other formats contain an image of the chart. On a system without the chart controls, loading a document inserts the image of each chart.
- **Charts in templates.** `MailMerge` fills charts with data. The data relation of a chart, the tables and the columns for its axis labels and values, is stored in the template and set with **Set Data Relation** on the **Chart Layout** ribbon tab. Charts are merged only outside merge blocks, and [ChartMerged](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-documentserver/mailmerge/chartmerged-event/llms-full.txt) occurs for each merged chart. The blog article [Using MailMerge with Chart Objects and JSON Data](https://www.textcontrol.com/blog/2019/07/18/using-mailmerge-with-chart-objects-and-json-data/) connects a chart to JSON data this way.

The blog article [Use Case: Blood Pressure Report with Charts in C#](https://www.textcontrol.com/blog/2023/04/27/use-case-blood-pressure-report-with-charts-in-csharp/) merges XML data into a template with two charts and a table of measurements. Its first two pages, exported to PDF, contain the charts as images:

![Two pages of a blood pressure report exported to PDF: a radar chart and a point chart of the measurements on the first page, and a table of the daily values on the second.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-server/chart-report-pages.4d87765b.webp)

### Next Steps

- [Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/barcodes/llms-full.txt): fill barcode placeholders with data in a mail merge.
- [Text Frames and Shapes](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/text-frames-shapes/llms-full.txt): place text and shapes in frames.
- [Headers and Footers](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/headers-footers/llms-full.txt): add content that repeats on every page.
- [Charts and Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/charts-barcodes/llms-full.txt) in the Document Editor: let users insert charts and barcodes.

---

## Nearby

- **Previous:** [Text Frames and Shapes](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/text-frames-shapes/llms-full.txt)
- **Next:** [Headers and Footers](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/headers-footers/llms-full.txt)
