New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@qctrl/visualizer

Package Overview
Dependencies
Maintainers
3
Versions
95
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@qctrl/visualizer - npm Package Compare versions

Comparing version 1.4.1 to 1.5.0

assets/labels/tetrahedron/XX.svg

130

components/index.js

@@ -142,36 +142,58 @@ "use strict";

containerWidth = _this$state.containerWidth;
var _this$props = this.props,
data = _this$props.data,
templateName = _this$props.templateName;
this.dataKeys = Object.keys(data).filter(function (key) {
return key !== "segmentIndexes";
});
var divNames = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
var templateName = this.props.templateName;
try {
for (var _iterator = this.dataKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var key = _step.value;
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
if (!this.divNames) {
var _this$props = this.props,
data = _this$props.data,
dataKeys = _this$props.dataKeys,
dataGroupKeys = _this$props.dataGroupKeys;
var ELEMENT_GROUPS = _constants.CONSTANTS.ELEMENT_GROUPS;
this.dataGroupKeys = dataGroupKeys || ELEMENT_GROUPS.filter(function (key) {
return data[key];
});
this.divNames = dataKeys || [];
if (this.divNames.length < 1) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator2 = data[key][Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var element = _step2.value;
divNames.push(element.name);
for (var _iterator = this.dataGroupKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var key = _step.value;
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = data[key][Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var element = _step2.value;
this.divNames.push(element.name);
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
if (_didIteratorError) {
throw _iteratorError;
}

@@ -181,34 +203,22 @@ }

}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
var template = (0, _templateGenerator.default)(templateName, this.divNames);
var gridTemplateAreas = template.gridTemplateAreas,
gridTemplateColumns = template.gridTemplateColumns,
gridTemplateRows = template.gridTemplateRows;
this.contentDivStyle = {
boxSizing: "border-box",
position: "absolute",
display: "grid",
top: "0",
left: "0",
width: "100%",
height: "100%",
zIndex: "1",
gridTemplateAreas: gridTemplateAreas,
gridTemplateColumns: gridTemplateColumns,
gridTemplateRows: gridTemplateRows
};
}
var template = (0, _templateGenerator.default)(templateName, divNames);
var gridTemplateAreas = template.gridTemplateAreas,
gridTemplateColumns = template.gridTemplateColumns,
gridTemplateRows = template.gridTemplateRows;
var contentStyle = {
boxSizing: "border-box",
position: "absolute",
display: "grid",
top: "0",
left: "0",
width: "100%",
height: "100%",
zIndex: "1",
gridTemplateAreas: gridTemplateAreas,
gridTemplateColumns: gridTemplateColumns,
gridTemplateRows: gridTemplateRows
};
return _react.default.createElement("div", {

@@ -232,4 +242,4 @@ ref: this.containerRef,

className: "content",
style: contentStyle
}, divNames.map(function (divName) {
style: this.contentDivStyle
}, this.divNames.map(function (divName) {
return _react.default.createElement("div", {

@@ -410,7 +420,7 @@ style: {

props = this.props,
dataKeys = this.dataKeys;
dataGroupKeys = this.dataGroupKeys;
this.canvasRef = canvasRef;
this.threeDivRefs = threeDivRefs;
this.props = props;
this.dataKeys = dataKeys;
this.dataGroupKeys = dataGroupKeys;
var data = props.data,

@@ -423,3 +433,3 @@ layout = props.layout;

this.finalFrameIndex = data.segmentIndexes.length - 1;
this.vectorisedData = (0, _vectoriseData.default)(data, this.finalFrameIndex, this.layout, threeDivRefs, dataKeys);
this.vectorisedData = (0, _vectoriseData.default)(data, this.finalFrameIndex, this.layout, threeDivRefs, dataGroupKeys);
this.vectorisedData.segmentIndexes = data.segmentIndexes; // get/set initial frameIndex

@@ -426,0 +436,0 @@

@@ -14,3 +14,3 @@ "use strict";

lighting: {
ambientColor: "#381E42",
ambientColor: "#6B5982",
pointLightIntensity: 3.5

@@ -26,3 +26,3 @@ },

y: 0,
z: 0.65
z: 0
},

@@ -34,6 +34,6 @@ labels: {

},
color: "#381E42",
outlineColor: "#C5CCD4",
color: "#6B5982",
outlineColor: "#D1C9D4",
opacity: 0.1,
metalness: 0.44,
metalness: 0,
roughness: 0.1,

@@ -40,0 +40,0 @@ lineWidth: 0.1,

{
"name": "@qctrl/visualizer",
"version": "1.4.1",
"version": "1.5.0",
"description": "An animated and interactive quantum state visualisation built with THREE.js and implemented as a React component",

@@ -5,0 +5,0 @@ "repository": {

@@ -1,1 +0,163 @@

2-Qubit Visualisation
# Visualizer
### Animated visualization for 1-qubit and 2-qubit controls
## Table of Contents
1. [Overview](#overview)
2. [Getting started](#getting-started)
3. [Usage](#props)
4. [Layout Settings](#layout)
5. [Data Format](#data)
6. [Code and Dev Guide](#code-and-development-guide)
7. [Publishing updates to NPM](#publishing-updates-to-npm)
## Overview
* This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).
* Packages are managed with [yarn](https://yarnpkg.com/)
* 3D using [THREE.js](https://threejs.org/), the [npm module version](https://www.npmjs.com/package/three) is being used.
* Camera controls utilising [three-orbit-controls](https://www.npmjs.com/package/three-orbit-controls)
* Code is formatted with [Prettier](https://prettier.io/)
## Getting started
#### Previewing the visualizer as a demo App
* Clone the repo
* On the command line `cd` into the repo and run `yarn`
* Run `yarn start`
* Open [http://localhost:3000/](http://localhost:3000/) in your browser if it
doesn't happen automatically
* Look at the file: `/src/ExampleImplementation.js` for an example of how Bloch Sphere components are implemented in a React App. This example is using dummy data from `/src/twoQubitTestData.js`
* See below for further props and settings to use with the component
#### Adding a Visualizer component to the Q-CTRL App / new React App
* Login to npm from the command line: `npm login` *your npm account must be linked and have access to the qtrl org*
* Install the Visualizer module with `yarn add @qctrl/visualizer`
* Import the Visualizer component to your App `import Visualizer from '@qctrl/visualizer'`
* See below and `/src/ExampleImplementation.js` in the repo for usage guidelines
## Usage: *Props* and *Layout*
#### Props
* The following props can be passed: `onUpdate`, `onError`, `isPlaying`, `progress`, `inputState`, `labels`, `cameraPreset`. Also `layout` and `data` which will be discussed further down.
* `onUpdate` should be a function that takes one argument, which will be a state object. ie:
```javascript
onUpdate={ object => {
this.setState(object);
}}
```
* `onError` If any errors are thrown within the visualizer component this function will be called (if it has been passed as a prop) with the errors object as the only argument:
```javascript
onError={errors => {
console.log(errors);
}}
```
* `inputState` an object with structure `{ x:<x>, y:<y>, z:<z> }` that will be set as an arbitrary starting / position for the pulse indicator
* `isPlaying` tells the Bloch sphere component to start or stop the animation
* `progress` will have the pulse path starting at the progress percent specified. Eg: if you want to have the whole path showing on mount set progress to `1`
```javascript
progress={<float between 0 and 1>}
```
* `Labels` needs to be an object with the following structure and will control the visibility of individual labels:
```javascript
{
xAxis: true,
yAxis: true,
zAxis: true,
theta: true,
thetaArc: true,
phi: true,
phiArc: true,
northPole: true,
southPole: true
}
```
#### Layout
* See the file `./src/lib/layout/index.js` to see what structure layout settings need to be in
* If no `layout` prop is passed, all default settings will be used from the layout settings file
* You are able to pass a subset of layout settings for a Bloch Sphere and these will be merged with the rest of the default settings from the settings file, no need to pass all the settings if you only need to customise a few things
#### Some common layout settings explained
* `animation: {fps: 30}` how many times per second the animation loop is called, changes the playback rate, animation will become choppy at lower rates
* `elementTypes` //TODO: add info about element layout settings
* `equatorialPlane: {}` is the face of the disc that spans the equator
* `equatorialOutline: {}` is the outline that runs around the surface of the equator
* `axes: {}` controls the guide x, y, z axes
* `pulsePoint: {}` changes the circle at the end of the pulse line. `radius` controls the size, `outlineFactor` controls how much larger than the main circle the outline is
* `pulseArcCurrentSegment: {}` controls the look of the currently animating pulse segment or the segment being hovered over after the animation has completed
* `pulseArc: { geometrySegments: 16 }`, ***needs to be set for larger block spheres for smooth looking points/circles***, default value is 6, this also applies to `pulsePoint: { geometrySegments: 16 }`
## Data
A data object must be passed as a prop called `data`
### Format/structure
#### Structure for 2-qubit-data:
```javascript
{
"qubits": [
{
"name": "qubit1",
"x": [],
"y": [],
"z": []
},
{
"name": "qubit2",
"x": [],
"y": [],
"z": []
}
],
"vectors": [
{
"name": "a",
"x": [], //xx
"y": [], //yy
"z": [] //zz
},
{
"name": "b",
"x": [], //xy
"y": [], //yz
"z": [] //zx
},
{
"name": "c",
"x": [], //xz
"y": [], //yz
"z": [] //zy
}
]
}
```
- See `twoQubitTestData.js` for a working example
## Code and Development Guide
* The React component lives in `BlochSphere/index.js`
* It is a React class component with internal state that controls animation and pulse path display
* A `ref` is used to get the div in the render function's reference and pass it to a scene manager so that canvas element that THREE.js will render to can be created
* The file: `/BlochSphere/threejs/scene.js` is imported to the React component file and is used to create a THREE.js `scene`, `renderer`, `camera` and `controls` which ae all returned as an object from the function nd stored as a Class variable in `this.SceneManager` this object now holds references to the above scene objects so they can be called in other places in the component
* The same pattern is used to create and reference objects in the scene such as the sphere and pulse lines
#### Custom Component Methods
* `threeRender()`, `animate()`, `update()` are all required by THREE.js to render an animate a scene
* `animate()` is called recursively via `requestAnimationFrame`
* All calculations for updating the positions and display of Bloch Sphere data is done here
* `componentDidMount()` is used to instantiate all THREE.js objects and add them to the scene / renderer
* `componentDidUpdate()` checks for new props and updates state appropriately, this allows the animation to be started and stopped and the display of the pulse path to be controlled via props
* `componentWillUnmount()` is used to clean up all THREE.js objects, the renderer and the animation loop to free up memory and GPU
* `_handleMouseMove()` is used to calculate mouse over effects for the pulse segments
#### Utils
Contains some specific maths functions for doing various circle / polar geometry stuff as well as some specific THREE.js utils / addons.
## Publishing updates to NPM
* Once you have made and tested your updates you first need to update the version number in `src/package.json`. The best way to do this is to cd into `src` from the command line and run `npm version <update_type>` *update_type* should be `patch`, `minor` or `major`, see [here](https://docs.npmjs.com/getting-started/semantic-versioning) for semantic versioning explanation
* from the project root run `npm run publishnpm` this will first build/compile using babel then publish the compiled lib to NPM. **Note that you need to be logged in to NPM and your account needs to be linked and have access to the qtrl Org**
* Everything under the `src/lib` folder will be compiled and published

@@ -15,3 +15,3 @@ "use strict";

BLOCHSPHERE = ELEMENT_TYPES.BLOCHSPHERE;
var blochSphereRegEx = new RegExp(ELEMENT_REGEX_STRINGS.BLOCHSPHERE, "gi");
var blochSphereRegEx = new RegExp(ELEMENT_REGEX_STRINGS.BLOCHSPHERE.join("|"), "i");
return blochSphereRegEx.test(elementId) ? BLOCHSPHERE : TETRAHEDRON;

@@ -18,0 +18,0 @@ };

@@ -87,3 +87,3 @@ "use strict";

this.currentPulseVector = this.data[this.frameIndex];
this.lights = (0, _objects.Lights)(radius, lighting.ambientColor, lighting.pointLightIntensity, origin);
this.lights = (0, _objects.Lights)(radius, lighting.ambientColor, lighting.pointLightIntensity, origin, elementType);
scene.add(this.lights); // create Axes

@@ -90,0 +90,0 @@

@@ -24,19 +24,19 @@ "use strict";

var _xx = _interopRequireDefault(require("../../../assets/labels/tetrahedron/xx.svg"));
var _XX = _interopRequireDefault(require("../../../assets/labels/tetrahedron/XX.svg"));
var _yy = _interopRequireDefault(require("../../../assets/labels/tetrahedron/yy.svg"));
var _YY = _interopRequireDefault(require("../../../assets/labels/tetrahedron/YY.svg"));
var _zz = _interopRequireDefault(require("../../../assets/labels/tetrahedron/zz.svg"));
var _ZZ = _interopRequireDefault(require("../../../assets/labels/tetrahedron/ZZ.svg"));
var _xy = _interopRequireDefault(require("../../../assets/labels/tetrahedron/xy.svg"));
var _XY = _interopRequireDefault(require("../../../assets/labels/tetrahedron/XY.svg"));
var _xz = _interopRequireDefault(require("../../../assets/labels/tetrahedron/xz.svg"));
var _XZ = _interopRequireDefault(require("../../../assets/labels/tetrahedron/XZ.svg"));
var _yx = _interopRequireDefault(require("../../../assets/labels/tetrahedron/yx.svg"));
var _YX = _interopRequireDefault(require("../../../assets/labels/tetrahedron/YX.svg"));
var _zx = _interopRequireDefault(require("../../../assets/labels/tetrahedron/zx.svg"));
var _ZX = _interopRequireDefault(require("../../../assets/labels/tetrahedron/ZX.svg"));
var _zy = _interopRequireDefault(require("../../../assets/labels/tetrahedron/zy.svg"));
var _ZY = _interopRequireDefault(require("../../../assets/labels/tetrahedron/ZY.svg"));
var _yz = _interopRequireDefault(require("../../../assets/labels/tetrahedron/yz.svg"));
var _YZ = _interopRequireDefault(require("../../../assets/labels/tetrahedron/YZ.svg"));

@@ -112,17 +112,17 @@ var _constants = require("../../../utils/constants");

case A:
xSVG = _xx.default;
ySVG = _yy.default;
zSVG = _zz.default;
xSVG = _XX.default;
ySVG = _YY.default;
zSVG = _ZZ.default;
break;
case B:
xSVG = _zx.default;
ySVG = _xy.default;
zSVG = _yz.default;
xSVG = _ZX.default;
ySVG = _XY.default;
zSVG = _YZ.default;
break;
case C:
xSVG = _zy.default;
ySVG = _xz.default;
zSVG = _yx.default;
xSVG = _ZY.default;
ySVG = _XZ.default;
zSVG = _YX.default;
break;

@@ -129,0 +129,0 @@

@@ -10,14 +10,24 @@ "use strict";

var _default = function _default(radius, ambientColor, PointLightIntensity, origin) {
var _constants = require("../../../utils/constants");
var _default = function _default(radius, ambientColor, PointLightIntensity, origin, elementType) {
var BLOCHSPHERE = _constants.CONSTANTS.ELEMENT_TYPES.BLOCHSPHERE;
var x = origin.x,
y = origin.y,
z = origin.z;
var position = new _three.Vector3(-radius + x, radius + y, -radius + z);
var innerPosition = new _three.Vector3(0.5 + x, -(0.5 + y), 0.8 + z);
var position = new _three.Vector3(radius + x, radius + y, radius + z);
var ambientLight = new _three.AmbientLight(ambientColor, 1.01);
var shaderLight = new _three.PointLight(0xffffff, PointLightIntensity);
var innerLight = new _three.SpotLight(0xffffff, 1.3, 1.6, Math.PI / 2, 0, 1);
var offsetLight = new _three.HemisphereLight(0x222222, 0xffffff, 1);
shaderLight.position.set(position.x, position.y, position.z);
innerLight.position.set(innerPosition.x, innerPosition.y, innerPosition.z);
var shaderLight = new _three.PointLight(0xffffff, 0, 0, 2);
if (elementType === BLOCHSPHERE) {
shaderLight.position.set(-position.x, position.y, -position.z);
shaderLight.intensity = PointLightIntensity;
} else {
shaderLight.position.set(position.x * 2, -position.y * 2, position.z);
shaderLight.intensity = PointLightIntensity / 3;
}
var innerLight = new _three.SpotLight(0xffffff, 1.3, radius * 2, Math.PI, 0, 0.5);
var offsetLight = new _three.HemisphereLight(0x111111, 0xffffff, 0.1);
innerLight.position.set(origin.x, origin.y, origin.z + radius / 2);
offsetLight.position.set(0 + x, -radius + y, 0 + z);

@@ -24,0 +34,0 @@ return new _three.Group().add(ambientLight, shaderLight, offsetLight, innerLight);

@@ -18,2 +18,3 @@ "use strict";

controls.enableKeys = false;
controls.update();
return controls;

@@ -20,0 +21,0 @@ };

@@ -17,38 +17,38 @@ "use strict";

XY: {
x: -12.199632825696328e-8,
y: -0.000008173490086527124,
z: 9.673738434763571
x: 0,
y: 0,
z: 11.8
},
YZ: {
x: 1.559808288297445625,
y: -9.64793338581103,
z: 2.14622326560449
x: 11.8,
y: 0,
z: 0
},
XZ: {
x: 9.648128499030603,
y: 1.51993625522885356,
z: 2.1462232656045861
x: 0,
y: -11.8,
z: 0
},
DEFAULT: {
x: 5.9,
y: 5.9,
z: 6.8
x: 7,
y: 7,
z: 6.5
},
FOV: 19
FOV: 17
},
BLOCHSPHERE: {
XY: {
x: 5.675415865985875e-8,
y: -0.00000942375581036714,
z: 9.423507839435171
x: 0,
y: 0,
z: 9.45
},
YZ: {
x: 9.423359777165494,
y: 0.004074292274836806,
z: -0.05266792391436967
x: 9.45,
y: 0,
z: 0
},
XZ: {
x: 0.05675163514073586,
y: -9.423336699735612,
z: -0.0021668617305596882
x: 0,
y: -9.45,
z: 0
},

@@ -71,2 +71,3 @@ DEFAULT: {

},
ELEMENT_GROUPS: ["qubits", "vectors"],
ELEMENT_TYPES: {

@@ -84,4 +85,4 @@ BLOCHSPHERE: "blochSphere",

ELEMENT_REGEX_STRINGS: {
BLOCHSPHERE: "blochphere|qubit",
TETRAHEDRON: "tetrahedron|tetrahedra|vector"
BLOCHSPHERE: ["blochphere", "qubit"],
TETRAHEDRON: ["tetrahedron", "tetrahedra", "vector"]
},

@@ -88,0 +89,0 @@ SCENE_OBJECT_UPDATE_TYPES: {

@@ -16,3 +16,3 @@ "use strict";

var _default = function _default(data, dataSize, layout, elementNames, dataKeys) {
var _default = function _default(data, dataSize, layout, elementNames, dataGroupKeys) {
var elementTypes = layout.elementTypes;

@@ -33,3 +33,3 @@ var vectorisedData = {};

try {
for (var _iterator = dataKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
for (var _iterator = dataGroupKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var key = _step.value;

@@ -42,2 +42,3 @@ var found = (0, _find2.default)(data[key], {

elementData = found;
break;
}

@@ -44,0 +45,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc