npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

protvista-zoomable

v3.8.22

Published

A zoomable component for ProtVista

Downloads

1,095

Readme

protvista-zoomable

A custom element to be inherited from if a Nightingale component needs zooming/panning capabilities that are compatible with protvista-manager.

Usage

Extend from ProtvistaZoomable instead of HTMLElement to have a protvista zoom-compatible object.

class YourComponent extends ProtvistaZoomable {
  // Here Your Code

  // Remember to implement a refresh method. This one wil be called on zooming events
  refresh() {
    // Anywhere you need the X position in pixels of a given base you can get it this way
    const xPosition = this.getXFromSeqPosition(5);
  }
}

Note: The svg DOM element of your component needs to be assigned to this.svg whenever you create it. It is in this point that zoomable attach the listeners of zoom/pan events.

Base coordinates and Seq positions

In this section I'll try to explain the coordinate system for Nightingale components. And how this is implemented for zoomable components.

The following example shows the logic to implement a sequence component, but the concepts should be the same for any type of track or component that needs to display coordinates that are aligned with other Nightingale components.

Given the following sequence of 10 amino acids: xxABCxxxxx

Let's assume the width given to the component is 100px, and the left and right margin has been set to 5 pixels.

Now if we use the protvista-sequence component specifying the coordinates to display between 3 and 5 (included). The code should be something like:

HTML:

<protvista-sequence id="seq1" length="10" displaystart="3" displayend="5" />

JavaScript:

document.querySelector("#seq1").data = "xxABCxxxxx";

The result of this should be something like:

     3   4   5           -> Sequence Position
|  |           |  |
|  |---|---|---|  |
|  | A | B | C |  |
|  |---|---|---|  |
|  |           |  |
|  |           |  |
0  5           95 100    -> Pixels

A couple of things to notice here:

  • The first base in the sequence correspond to position 1. And therefore in the given example position 3 correspond to the base A.

  • The sequence base indicated in thedisplayend parameter, is included in the graphic. That's why C which position is 5 is included in the result.

  • Because of the margin, the actual drawing area is between pixels 5 and 95

  • The actual drawing area is the equally divided for each of the visible bases. In the example, the actual area is 90, giving each of the bases 30 pixels to be drawn, and including the margin the bases should be draw:

    • A: 5 to 34
    • B: 35 to 64
    • C: 65 to 94

In conclusion, if a component makes sure to be drawn following these rules within the refresh() method, all zooming and padding should work if the component inherits from ProtvistaZoomable, and the component is a DOM descendent of protvista-manager.

How does it work?

We use the D3 module scaleLinear to calculate the positions, and connect the D3 zoom handler to the svg.

The interaction with a zoomable component has 2 parts:

  1. The observed attributes of protvista-zoomable are: ["displaystart", "displayend", "length"]. If any of these attributes changes, the scale gets updated to match the new start/end coordinates and the refresh method is called.
  2. When a zooming event is trigger, the scale gets updated by scaling the current values. A change event is dispatched, notifying the new displaystart and displayend values.
    If there is a protvista-manager listening to this event, it will propagate the new values to all its registered children, which will trigger the case 1, for any zoomable component in there.

API Reference

Properties

name: use-shift-to-zoom Boolean

If this attribute is present, the zooming only works while the [Shift] key is pressed.

name: length Number

Number of bases of the sequence to be displayed.

name: displaystart Number

First base to be displayed.

name: displayend Number

Last base to be displayed.

highlight: string (optional)

A comma separated list of regions to highlight.

Each region follows the format: [start]:[end], where both [start] and [end] are optional numbers.

Examples:

  • 10:20 Highlight from base 10 to 20 including both.
  • 10:20,30:40 Highlight from base 10 to 20, and from 30 to 40.
  • :20 Highlight from the first base (1) to 20.
  • 10: Highlight from base 10 to the end of the sequence.
  • : Highlight the whole sequence.

Methods

constructor()

The constructor of this class, initialises the zoom, bind some of its methods, and start listening for resizing events.

connectedCallback()

  • Calculates the width of the component.
  • Makes sure the observable attributes get assigned as floats.
  • Updates the scale, re-initialises the zoom and the resizing observer.

Note: If you are overwriting this method in your component, make sure to call it as super.connectedCallback(); inside your method or the zooming functionality might be compromised.

disconnectedCallback()

Disconnects the resize observer.

observedAttributes()

The observed attributes are: ["displaystart", "displayend", "length"].

Note: If you are overwriting this method in your component, make sure to include those defined here, otherwise the zooming functionality might be compromised. For example:

 static get observedAttributes() {
   return ProtvistaZoomable.observedAttributes.concat(
     "highlightstart",
     "highlightend",
   );
 }

attributeChangedCallback(name, oldValue, newValue)

  • Makes sure the observable attributes get assigned as floats.
  • Triggers the re-calculation of the scale.

Note: If you are overwriting this method in your component, make sure to call it as super.attributeChangedCallback(name, oldValue, newValue); inside your method or the zooming functionality might be compromised.

get margin()

Returns the default values of the margin. you should overwrite this to define your own margins. The default values are:

{
  top: 10,
  right: 10,
  bottom: 10,
  left: 10
}

getWidthWithMargins()

Returns the current available width, excluding the margins.

getXFromSeqPosition(position)

Returns X coordinate in pixels for a given position. The position should be a number between 1 and the length of the sequence.

getSingleBaseWidth()

Returns the width of a single base using the current scale.

Events

change

It reports a change in the coordinates, which most likely have been caused by a zoom/panning event. The detail of the event includes the new coordinates. For example:

{
  detail: {
    displaystart: 3,
    displayend: 5
  }
}

Events bound to track features

By default, onmouseover, onmouseout and onclick events are attached to features. They trigger a change event, which is used to update the highlight, but you can also use them to display things like tooltips, as the event payload will contain the data point as well as x and y coordinates of the click event.