spectator-document-viewer
TypeScript icon, indicating that this package has built-in type declarations

0.1.0 • Public • Published

Document Viewer

The document viewer is a React component built in Typescript that allows a user to highlight parts of the text in order to create annotations.

Getting started

You will need node and yarn.

yarn install to install the document viewer's dependencies.

There's a playground that enables faster local development with a very simple test document (see playground folder). It uses (MirageJS)[https://miragejs.com/] to mock the server API.

  1. yarn install in the playground directory.
  2. yarn start will start server with hot-reload. Simply navigate to http://localhost:1234.

yarn build packages the component so that it's ready to be used in another project.

React component

The component can be rendered in any space, but it is recommended to allow the component to use all the width and height of the viewport for optimal usage.

A quick example of how to use it would be:

<div className="App" style={{height: "100%", width: "100%", margin: "0"}}>
  <DocumentViewer
    annotations={[{
      characterStart: 0,
      characterEnd: 19,
      pageStart: 1,
      pageEnd: 1,
      top: 304,
      left: 301,
      topic: "1"
    }]}
    name={"document.pdf"}
    lazyLoadingWindow={5}   // optional
    onAnnotationCreate={(annotation => console.log(annotation))}
    onAnnotationDelete={(annotation => console.log(annotation))}
    onClose={() => console.log('Close')}
    onNextDocument={() => console.log('Next')}
    onPreviousDocument={() => console.log('Previous')}
    pages={[{
      originalHeight: 842,
      originalWidth: 595,
      imageURL: "api/document/1/page/1/image", 
      tokensURL: "api/document/1/page/1/tokens"
    }]}
    topics={["1", "2", "3"]}
  />
</div>

Concepts

As a document viewer is somewhat of a complex user interface to build, it requires some concepts to be understood:

  • annotations: They are the highlights in the text. An annotation is mainly defined by the [characterStart characterEnd[ pair and should, as much as possible, correspond with the start and the end of a word. If the annotation doesn't wrap nicely, the document viewer will do its best to try to map it to the closest words.
    • characterStart: The 0-based index of the first character of the highlight.
    • characterEnd: The 0-based index of the last character of the highlight.
    • pageStart: The 1-based index of the page containing characterStart.
    • pageEnd: The 1-based index of the page containing characterEnd.
    • top and left corresponds to the top and left position, in pixels, of the first character of the annotation in the original document. It is used to be able to jump directly to annotations.
    • topic: The string representation of the topic.
  • name: The name of the document.
  • lazyLoadingWindow (optinal): As the document viewer is taking care of lazy loading the pages, it defines how many pages on both sides needs to be loaded. A value of 1 will mean to load 3 pages (-1, current, +1).
  • onAnnotationCreate: A callback used when a user highlights text and then click on a topic.
  • onAnnotationDelete: A callback used when a user clicks on the X of an annotation.
  • onClose: A callback used when a user clicks on the X of the document viewer.
  • onNextDocument: A callback used when a user clicks on the -> of the document viewer.
  • onPreviousDocument: A callback used when a user clicks on the <- of the document viewer.
  • pages: The definition of all pages. The page are lazy loaded which is why it requires some URLs in its definition.
    • originalHeight: The height, in pixels, of the original document. It is used to be able to create a translate the position of the mouse to something we can use the R-tree with.
    • originalWidth: The width, in pixels, of the original document. It is used to be able to create a translate the position of the mouse to something we can use the R-tree with.
    • imageURL: The URL to the image of the page. The PNG format is recommended as it performs well for our scenario.
    • tokensURL: The URL to the tokens of the page. As there's normally a lot of tokens inA token is defined by:
      • line: The 0-based index of the line containing the token. The line is supposed to reset to 0 when it's a new page.
      • characterStart: The 0-based index of the first character of the token.
      • characterEnd: The 0-based index of the last character of the token.
      • boundingBox: The enclosing box wrapping the token.
        • top: Position in pixels of top in the original document.
        • bottom: Position in pixels of bottom in the original document.
        • left: Position in pixels of left in the original document.
        • right: Position in pixels of right in the original document.
  • topics: An order list of topics (strings) to choose from.

Design

The document viewer loads the original image of the pages and overlays an R-tree containing all the tokens in the page. When a user selects text, in reality, it keeps track of the mouse position, will translate the coordinates to what it will be in the original document. It will then query the R-tree and return the tokens that intersect with the rectangle created by the selection. As highlighting a passage in the text happens way less often than reading the document, we made the tradeoff of keeping the visualization part of the document viewer simple (loading the original image) while bringing more complexity on the text selection part.

A word on annotation colours

To have a maximal number of distinct colours (12 colours), we used a generator. As we don't want the highlight to block the text, we reduced the opacity of the colours and we used the css property mix-blend-mode to multiply. It still doesn't prevent a user from massively highlighting the text to a point you can't see the text well.

Features that are left out (for now)

  • Search within and between documents.
  • Copying text.
  • Nuanced behaviour tracking.
  • Mobile/Tablet support.

Readme

Keywords

none

Package Sidebar

Install

npm i spectator-document-viewer

Weekly Downloads

1

Version

0.1.0

License

none

Unpacked Size

507 kB

Total Files

29

Last publish

Collaborators

  • cmlenius