▸   Home

Documentation

Declarative Usage

1000words.js allows interactive graphical views to be built declaratively. This means the application only needs to specify what it wants to achieve and the library is tasked with how to achieve it.

Application responsibilities:

The library does the heavy lifting of:


1. Concepts
2. Shape Types
3. Shape Position
4. Shape Detail Level
5. Layers
6. Creating Views
7. Events
8. Modifying Shape Attributes
9. Modifying Shape Position
10. Drilldown
11. Complete Example
12. API
13. Misc
14. Development Workflow


  1. Concepts
  2. Interactive scenes (Views) are instantiated by 1000Words.js in a DOM element specified by the application.

    Views contain Shapes.

    Shapes are instances of Shape Types.

    The application specifies each shape's position (x, y) expressed as a percentage of the view's width and height.

    The definition of what a shape looks like is defined once per Shape Type in the form of SVG (string snippets).

    Views can be configured to publish events when a shape is clicked, comes into focus, the viewport changes etc. The application can subscribe to these events.

    Shape Groups contain one or more shape instances, of one or more shape types, and are used to configure:

    Drilldown into shapes is supported. When a user dives into (zooms in) a shape configred for drilldown, a new sub-view is opened up. One or more shapes in the new view can, in turn, be configured for drilldown (recursive).

    Infinite Canvas can be used for very large screens. A summary or Overview is provide to accompany the Primary View. The overview provides a quick look at what part of the main view is currently visible. It comes with a Viewport Controller which users can drag to quickly pan across the primary view as desired.

    ▸   Home

  3. Shape Types
  4. A shape type (e.g. Car, Circle, House, Hospital) is expressed as a class that extends the library's built-in shape class

    Shape Class
    
                const DomainShape = $1000Words.import('DomainShape');
                export default class Car extends DomainShape {
                    renderContents(node, detailLevel) {...} // shape svg string injection
                }
                        

    Shape SVG
    
                // The standardized definition of a shape should render inside a box with
                // 0x0 and 100x100 as the top-left and bottom-right corners.
    
                // NOTE: The shape definition is independent of how 'large' shape
                // instances are or 'where' they are placed on the scene.
    
                // square
                <rect x="0" y="0" width="100" height="100" stroke="red"></rect>
    
                // circle
                <circle cx="50" cy="50" r="50" stroke="blue"></circle>
    
                // shape with a bunch of paths
                <g>
                    <path d="m22.16 ..." stroke="green"></path>
                    <path ...></path>
                    <path ...></path>
                </g>
                    

    Three shape definitions in the form of a square, circle and collection of paths.

  5. Shape Position
  6. The position is specified in percentage terms when the shape is created.

    Specifying position
    
                $1000Words.createShape(Car, "car-fred", view, options, 10, 8);
                $1000Words.createShape(Car, "car-jimmy", view, options, 85, 90);
                $1000Words.createShape(Truck, "company-truck", view, options, 50.21, 60.07);
                        

    Two cars and a truck.

  7. Shape Detail Level (configured via Shape Groups)
  8. For graphical scenes, things typically get more detailed as the user zooms in. When using 1000Words.js, it isn't strictly necessary to show shapes in greater level of detail as the user zooms in. However the UX design of the scene can often involve showing shapes at different amounts of detail, depending on the zoom level.

    Shape Groups
    
            const ShapeConfigurations = $1000Words.import('ShapeConfigurations');
            const configs = new ShapeConfigurations( {
                shapeTypes: [], // optional - use when svg referenced elements are used
                groups: [{
                        name: 'trees',
                        existences: {1 : 0.5, 20 : 0}, // covered in the 'layers' section
                        resolutions: {1 : 'low', 3: 'medium', '8': 'high' },
                        // show the high fidelity version of tree when zoom level goes to 8
                        // and above and medium fidelity version when zoom level goes below 8
                    ...
                }]
            })
            ...
            $1000Words.createView('Main View', container, configs, onEvent, eventsOfInterest)
            .then( view => {...} )
    
                        

    Note: The zoom levels at which shape resolutions can change isn't fixed and is determined by the application. The application needs to provide the rendering of the svg shape at different fidelity levels.
    Configurable combinations of zoom and detail level
    
            resolutions: {1 : 'low', 2: 'medium', '8': 'high'}
            resolutions: {1 : 'low', 3: 'medium', '4': 'high', '12': 'superhigh'}
            resolutions: {1 : 'far away', 9': 'clear sight', '14': 'rubbing noses'}
            resolutions: {1 : 'standard'} // fixed resolution, independent of zoom level
            // 1000Words.js will determine when it is time to display a shape at a different detail
            // level and ask the shape for the SVG that corresponds to that level (e.g. 'clear sight')
                        

    If a house shape is displayed on a scene, the application could decide to show different house details at different levels of zoom, say 'low', 'medium' and 'high'.

    low       medium     high
     Shape Definitions (100x100) for different zoom levels



     Scene at a low level of zoom



     Scene at a medium level of zoom



     Scene with a high level of zoom


  9. Layers (configured via Shape Groups)
  10. Layers allow groups of shapes to come into or go out of existence. Scene designers can find many creative uses for layers. Two, out of potentially many, potential uses are outlined below:

    1. Depth. When the scene naturally contains depth or the application designer is able to creatively visualize a complex technical domain using depth
    2. Marker Shapes. When a group of shapes with their natural screen size are too small to be seen without zooming in, and users need a hint of what lies there

    Layers - Depth
    
            const ShapeConfigurations = $1000Words.import('ShapeConfigurations');
            const configs = new ShapeConfigurations( {
                shapeTypes: [], // optional - use when svg referenced elements are used
                groups: [{
                        name: 'big',
                        existences: {1: 20, 10 : 0}, // the shapes included in the
                        // 'big' group will be visible in the beginning (zoom = 1) with a size
                        // of 20% of the view and will be hidden when the user zooms past 10
                        resolutions: {1 : 'standard'}
                    ...
                },
                {
                        name: 'medium',
                        existences: {12 : 10, 15: 0}, // 10% of viewport when zoom is 12
                        resolutions: {4 : 'standard' }
                    ...
                },
                {
                        name: 'small',
                        existences: {150 : 7, 30: 0},
                        resolutions: {20 : 'standard' }
                },
                {name: 'tiny ...}, {name: 'miniscule ...}, {microscopic ...}
            })
            ...
            $1000Words.createView('Main View', container, configs, onEvent, eventsOfInterest)
            .then( view => {...} )
                        


    Fishes arranged from top to bottom, arranged by size
    (100s of fish that are too small to be seen, are hidden at first)

     Zoom level 1



     Zoom level 12



     Zoom level 150

    Layers - Marker Shapes
    
                const ShapeConfigurations = $1000Words.import('ShapeConfigurations');
                const configs = new ShapeConfigurations( {
                    shapeTypes: [], // optional - use when svg referenced elements are used
                    groups: [{
                            name: 'settings-marker',
                            existences: {1 : 1, 20 : 0},
                            resolutions: {1 : 'standard'}
                        ...
                    },
                    {
                            name: 'settings',
                            existences: {20 : 8},
                            resolutions: {20 : 'standard' }
                        ...
                    }]
                })
                ...
                $1000Words.createView('Main View', container, configs, onEvent, eventsOfInterest)
                .then( view => {...} )
                        


    Individual Settings Icons are too small to be seen so a marker shape is used




  11. Creating Views
  12. Views are created inside a placeholder DOM element created by the application. Views need to be created prior to creating individual shapes. View creation takes the following inputs:

    view creation
    
            const ShapeConfigurations = $1000Words.import('ShapeConfigurations');
            const EventType = $1000Words.import('EventType');
            const ShapeEventType = $1000Words.import('ShapeEventType');
    
            const onEvent = (event) => console.log(event);
            const container = document.getElementById("my-view-container");
    
            // see 'Layers' & 'Shape Detail Level' for details on shape configs
            const configs = new ShapeConfigurations( {...} );
    
            const events = [ShapeEventType.IN_FOCUS, ShapeEventType.SELECT, EventType.VIEWPORT];
            $1000Words.createView(viewName, container, configs, onEvent, events)
            .then( view => {
                const shape1 = $1000Words.createShape(type1, id1, view, options, x1, y1);
                const shape2 = $1000Words.createShape(type2, id2, view, options, x2, y2);
                view.initialize(...);
            });
    
                        

  13. Events
  14. Applications can subscribe to various events of interest, emitted by the library.

    events
    
            const ShapeConfigurations = $1000Words.import('ShapeConfigurations');
            const EventType = $1000Words.import('EventType');
            const ShapeEventType = $1000Words.import('ShapeEventType');
    
            const onEvent = (event) => console.log(event);
            const events = [ ShapeEventType.IN_FOCUS, ShapeEventType.SELECT,
                              EventType.VIEWPORT_EVENT ];
            $1000Words.createView(viewName, container, configs, onEvent, events)
            .then( view => {...}
    
                        

    List of events.

  15. Modifying Shape Attributes
  16. coming soon...

  17. Drilldown
  18. coming soon...

  19. Complete Example
  20. coming soon...

  21. API
  22. coming soon...

  23. Misc

  24. Development Workflow
  25. coming soon...