Encode diagrams

When using GET requests, your diagram must be encoded in the URL using a deflate + base64 algorithm. On this page you will learn how to encode a diagram using:

Node.js

To compress our diagram with deflate algorithm, we are going to use pako — a high speed zlib port to JavaScript. Once pako is installed, you can use the deflate method:

const pako = require('pako')

const diagramSource = `digraph G {
  Hello->World
}`

const data = Buffer.from(diagramSource, 'utf8') 
const compressed = pako.deflate(data, { level: 9 }) 
const result = Buffer.from(compressed)
  .toString('base64') 
  .replace(/\+/g, '-').replace(/\//g, '_') 

console.log(result)
1 Create a Buffer from the diagram source using the default UTF-8 encoding
2 Compress data with deflate algorithm using a compression level of 9 (best compression).
3 Create a Buffer from the compressed data and encode to Base64
4 Replace + and / characters to make it "URL safe"

JavaScript

We recommend to encode your diagram as UTF-8. To do so, we can use TextEncoder:

new TextEncoder('utf-8').encode(diagramSource)

Unfortunately TextEncoder is not yet available on all browsers. To workaround this issue, we can define a function to encode our diagram:

function textEncode(str) {
  if (window.TextEncoder) {
    return new TextEncoder('utf-8').encode(str);
  }
  var utf8 = unescape(encodeURIComponent(str));
  var result = new Uint8Array(utf8.length);
  for (var i = 0; i < utf8.length; i++) {
    result[i] = utf8.charCodeAt(i);
  }
  return result;
}

The above code will use TextEncoder if it’s available and otherwise it will use a fallback implementation.

Now that our diagram is encoded as UTF-8 in a Uint8Array, we can use pako to compress it. As a reminder, pako is a high speed zlib port to JavaScript:

<script src="https://unpkg.com/pako@1.0.10/dist/pako_deflate.min.js"></script>

To compress our diagram diagram we are going to use the deflate method provided by pako:

var diagramSource = 'digraph G { Hello->World }'

var data = textEncode(source) 
var compressed = pako.deflate(data, { level: 9, to: 'string' }) 
var result = btoa(compressed) 
  .replace(/\+/g, '-').replace(/\//g, '_') 

console.log(result)
1 Encode the diagram as UTF8 in a Uint8Array (using the textEncode function declared above)
2 Compress data with deflate algorithm using a compression level of 9 (best compression). pako is available as a global variable.
3 Encode to Base64 using btoa global function
4 Replace + and / characters to make it "URL safe"

Python

import sys;
import base64;
import zlib;

print(base64.urlsafe_b64encode(zlib.compress(sys.stdin.read(), 9)))

Java

package main;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.zip.Deflater;

public class Encode {

  public static byte[] encode(String decoded) throws IOException {
    return Base64.getUrlEncoder().encode(compress(decoded.getBytes()));
  }

  private static byte[] compress(byte[] source) throws IOException {
    byte[] result = new byte[2048];
    Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION);
    deflater.setInput(source, 0, source.length);
    deflater.finish();
    int compressedLength = deflater.deflate(result, 0, source.length, Deflater.FULL_FLUSH);
    deflater.end();
    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
      byteArrayOutputStream.write(result, 0, compressedLength);
      return byteArrayOutputStream.toByteArray();
    }
  }
}

Go

package main

import (
	"bytes"
	"compress/zlib"
	"encoding/base64"

	"github.com/pkg/errors"
)

// Encode takes a string and returns an encoded string in deflate + base64 format
func Encode(input string) (string, error) {
	var buffer bytes.Buffer
	writer, err := zlib.NewWriterLevel(&buffer, 9)
	if err != nil {
		return "", errors.Wrap(err, "fail to create the writer")
	}
	_, err = writer.Write([]byte(input))
	writer.Close()
	if err != nil {
		return "", errors.Wrap(err, "fail to create the payload")
	}
	result := base64.URLEncoding.EncodeToString(buffer.Bytes())
	return result, nil
}