home | introduction | examples | features | manual | site map | contact

embedding brat visualisations

This document provides an example of how to embed brat visualisations into any homepage and how it can be used as a stand-alone server-less visualisation of the output of your own tools or to illustrate examples of text annotations.

Throughout this document we will use "Ed O'Kelley was the man who shot the man who shot Jesse James." as our example text, we will produce both annotation configurations and annotations that are given to brat using JSON. We will also take the opportunity to embed the very same examples that we are creating into this page to give you an instant preview of the end results.

If you just want a quick glance of what can be achieved by embedding brat, do skip ahead to the live example at the end of the page and save the technical instructions for later.

prerequisites

Since brat embeds an SVG image in your document, your document should be XHTML compliant, otherwise the embedding won't show up properly. The first step necessary is to include the brat visualisation style-sheet. Do so by including the line below in the head of your XHTML document.


<link rel="stylesheet" type="text/css" href="http://${YOUR_BRAT_INSTALLATION}/style-vis.css"/>

brat uses head.js to load its scripts in parallel, thus for the purpose of this tutorial you also need to include head.js into the head of your XHTML document.

If you are an experienced developer and prefer to load scripts in a different fashion, feel free to skip this step and adjust the rest of the tutorial accordingly.


<script type="text/javascript" src="http://${YOUR_BRAT_INSTALLATION}/client/lib/head.load.min.js"></script>

initialisation

From this point onwards all examples are given as Javascript code. These should be embedded in a script tag after you have imported head.js. The code below tells head.js to include the visualisation components of the brat client and its dependencies.


var bratLocation = '${YOUR_BRAT_INSTALLATION}';
head.js(
    // External libraries
    bratLocation + '/client/lib/jquery.min.js',
    bratLocation + '/client/lib/jquery.svg.min.js',
    bratLocation + '/client/lib/jquery.svgdom.min.js',

    // brat helper modules
    bratLocation + '/client/src/configuration.js',
    bratLocation + '/client/src/util.js',
    bratLocation + '/client/src/annotation_log.js',
    bratLocation + '/client/lib/webfont.js',

    // brat modules
    bratLocation + '/client/src/dispatcher.js',
    bratLocation + '/client/src/url_monitor.js',
    bratLocation + '/client/src/visualizer.js'
);

brat also needs to have access to the location the fonts it uses for rendering. The code below declares where the client can find them relative to your brat installation.


var webFontURLs = [
    bratLocation + '/static/fonts/Astloch-Bold.ttf',
    bratLocation + '/static/fonts/PT_Sans-Caption-Web-Regular.ttf',
    bratLocation + '/static/fonts/Liberation_Sans-Regular.ttf'
];

Now, we can call upon brat once the scripts have been successfully loaded. The relevant call is to Util.embed with the data that you want to visualise, we will go through the structure of these objects in the following sections.


head.ready(function() {
    Util.embed(
        // id of the div element where brat should embed the visualisations
        '${DIV_ID}',
        // object containing collection data
        collData,
        // object containing document data
        docData,
        // Array containing locations of the visualisation fonts
        webFontURLs
        );
});

entities

The simplest form of annotation in brat are spans (internally referred to as entities). They can be used to represent named entities, part-of-speech tags and much more. As with all annotations in brat they can be configured to your liking. Below is an example configuration of a person annotation that is to be added to the collection data object.


var collData = {
    entity_types: [ {
            type   : 'Person',
            /* The labels are used when displaying the annotion, in this case
                we also provide a short-hand "Per" for cases where
                abbreviations are preferable */
            labels : ['Person', 'Per'],
            // Blue is a nice colour for a person?
            bgColor: '#7fa2ff',
            // Use a slightly darker version of the bgColor for the border
            borderColor: 'darken'
    } ]
};

Now that we have instructed brat as to how we want the annotations to be displayed, we can add person annotations to the document object.


var docData = {
    // Our text of choice
    text     : "Ed O'Kelley was the man who shot the man who shot Jesse James.",
    // The entities entry holds all entity annotations
    entities : [
        /* Format: [${ID}, ${TYPE}, [[${START}, ${END}]]]
            note that range of the offsets are [${START},${END}) */
        ['T1', 'Person', [[0, 11]]],
        ['T2', 'Person', [[20, 23]]],
        ['T3', 'Person', [[37, 40]]],
        ['T4', 'Person', [[50, 61]]],
    ],
};

Below is how brat visualises the entity example.

attributes

brat supports several other annotation primitives, let's look at the simplest annotation type that references another annotation, attributes. Now, our example contained three pretty notorious historical figures, however, one must be said to be a lot more notorious than the others so, let's create an attribute "Notorious" to mark him as such.


collData['entity_attribute_types'] = [ {
    type  : 'Notorious',
    /* brat supports multi-valued attributes, but in our case we will only
        use a single value and add a glyph to the visualisation to indicate
        that the entity carries that attribute */
    values: { 'Notorious': { 'glyph': '★' } }
} ];

Once we have the configuration in place, we can add an attribute annotation similarity to how we added the entity annotations. The main difference is that we will have a reference to the "Jesse James" person annotation that had the id "T4".


docData['attributes'] = [
    // Format: [${ID}, ${TYPE}, ${TARGET}]
    ['A1', 'Notorious', 'T4']
];

And we can now see that "Jesse James" has been marked with a neat Unicode star to signify his notoriety.

relations

Let us now consider relational annotations, these are more complex than attributes but are also far more powerful. We could use them to visualise dependency, part-of and instance-of relations, but in our example we will use them to annotate anaphoras.


collData['relation_types'] = [ {
    type     : 'Anaphora',
    labels   : ['Anaphora', 'Ana'],
    // dashArray allows you to adjust the style of the relation arc
    dashArray: '3,3',
    color    : 'purple',
    /* A relation takes two arguments, both are named and can be constrained
        as to which types they may apply to */
    args     : [
        // 
        {role: 'Anaphor', targets: ['Person'] },
        {role: 'Entity',  targets: ['Person'] }
    ]
} ];

docData['relations'] = [ 
    // Format: [${ID}, ${TYPE}, [[${ARGNAME}, ${TARGET}], [${ARGNAME}, ${TARGET}]]]
    ['R1', 'Anaphora', [['Anaphor', 'T2'], ['Entity', 'T1']]]
];

And the annotation visualisation now clearly shows that the first man mentioned in "the man who shot the man who shot..." clearly was "Ed O'Kelley".

events

Now, to the most interesting and involved annotation primitive, the N-ary event structures.


collData['event_types'] = [ {
    type   : 'Assassination',
    labels : ['Assassination', 'Assas'],
    bgColor: 'lightgreen',
    borderColor: 'darken',
    /* Unlike relations, events originate from a span of text and can take
        several arguments */
    arcs   : [
        {type: 'Victim', labels: ['Victim','Vict'] },
        // Just like the event itself, its arguments can be styled
        {type: 'Perpetrator', labels: ['Perpetrator','Perp'], color: 'green' }
    ]
} ];

/* Events also have trigger annotations, these are spans that are not
    visualised. This enables sharing of triggers when this is desirable, such
    as in the sentence "He robbed the bank and the post office", where
    "robbed" gives rice to two separate events that shares a single trigger */
docData['triggers'] = [
    // The format is identical to that of entities
    ['T5', 'Assassination', [[45, 49]]],
    ['T6', 'Assassination', [[28, 32]]]
];

docData['events'] = [
    // Format: [${ID}, ${TRIGGER}, [[${ARGTYPE}, ${ARGID}], ...]]
    ['E1', 'T5', [['Perpetrator', 'T3'], ['Victim', 'T4']]],
    ['E2', 'T6', [['Perpetrator', 'T2'], ['Victim', 'T3']]]
];

And now... our little western example fully captures our murderous trio.

live embedding

brat has a lot more functionality than what we have had time to cover in this tutorial. Below are two interactive text areas that are coupled to the visualisation above them, inside the text areas is a JSON version of the collection and document object respectively.

As you change the JSON, the visualisation will change accordingly, you can use this to experiment with how the visualisation works. Some things you may want to try out is to change the target of the event arguments and relations, removing the entire style to see that brat still does its best to visualise your annotations. We hope that at this point you may already have some ideas on how you could use brat for your own visualisation needs and how it can be used separately from its original visualisation/annotation application.

If you feel up to it, you can also view the XHTML and Javascript source contained in this very page and see how we embedded brat to create a tutorial on how to embed brat.