[Learning Notes] Hightopo’s HT for Web (1) - Basic Conceptions
Tags: hightopo, learning, webdev, javascript
Published: 2023-05-30 08:19:47

**HT for Web**, typically abbreviated as `HT`, is a `WebGL` engine developed using `JavaScript`. It can be used for 2D/3D visualization development. The engine consists of only one core file, **"ht.js"**, which can be directly imported in the `index.html` using the `script` tag. The file size is approximately 1MB.

```
<body>
    <script src="lib/core/ht.js"></script>
</body>
```

Due to its strong scalability, it also provides a series of plugins. For example: edges, animation, obj, right-click menu, etc. These can be imported as needed during development.

This engine is independently developed by **Hightopo** company. After more than 10 years of continuous iteration and optimization, it has excellent performance in terms of learning curve, development efficiency, rendering effect, and operational performance.

[**Hightopo** official website demo cases](https://hightopo.com/demos/en-index.html)

![demos](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k18mstrkou8rbbpbuc67.png)
One disadvantage of this engine is that it is not open source and requires a commercial license to use. However, interested developers can apply for a free trial package from its official website. This trial package includes not only the core engine files, but also user manuals and a large number of plugins. The trial period is usually three months, but we can continue to apply for it after it expires. The following are the plugins included in my trial package:

**Apply for trial**: [https://www.hightopo.com/en-request.html](https://www.hightopo.com/en-request.html)

![plugins](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vdj0wjy1xbspg5wqj06w.png)
The main content of this chapter is to help everyone clarify the basic concepts in `HT for Web`, which will facilitate understanding in subsequent chapters.

### Basic Data - ht.Data

**`ht.Data`**, also called `Data` for short, is the most basic data type (or data element) in `HT for Web`. For example, if a table has 3 rows, each row can be represented using one `Data`.

![table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6pfk6mhfnifz51v4crz.png)
In `Data`, we can store and configure custom data. For example, in the first row of the table above, we can use a `Data` to store its row data:

```
let row1 = new `ht.Data`(); // Create a new `ht.Data` to storage row data

// Assign a value to `Data` (row data). 
// The "key" is before the colon, and the displayed value is after the colon.
// As for how the key is bound to the table column data, 
// this will be described in the table chapter later.
row1.a({
  "empNo": "ht424",
  "name": "Donnie",
  "sex": "Male",
  "job": "CEO"
});

let table = new ht.ui.TableView(); // create the table
table.dm().add(row1); // add the row data to the table. table.dm() is the DataModel
```

In the above code, `row1.a()` is a shorthand for `row.setAttr()`. It is used to store custom attributes in the `Data` object.

After storing data in a `Table`, if we want to know the total number of rows in the current `Table` or want to listen to operations such as adding, deleting, selecting, and deselecting for each row and perform further processing, we need to use data models and selection models.

### Data Model (Container) - ht.DataModel

**ht.DataModel**, also known as `DataModel` or dm, is a container used to store and manage `ht.Data`. `DataModel` is also a fundamental concept in `HT  for Web`. Tables, lists, 2D displays, 3D scenes, and other components in `HT` all use `DataModel` to manage their data. Therefore, once you have a clear understanding of the relationship and roles of `ht.Data` and `ht.DataModel`, using various `HT` components will become much easier.

`DataModel` is a container that different view components of `HT` (such as tables, lists, 2D drawings, 3D scenes, etc.) will use to manage the `Data` underneath. The only difference is that each `Data` has a different representation in different view components.

Each view component has the `getDataModel()` and `setDataModel()` methods, which are used to get and set the `DataModel` used by the component. For example:

```
let table = new ht.ui.TableView(); // create the table
const dm = table.getDataModel(); // get the `DataModel` of the table
// const dm = table.dm(); // same as table.getDataModel()

// Set the `DataModel` of the table
const newDM = new ht.DataModel();
table.setDataModel(newDM); // set the `DataModel` of the table
// table.dm(newDM); // same as table.setDataModel(newDM)
```

For the convenience of writing code, you can use `dm()` instead of `getDataModel()` and `setDataModel()` methods. If there are no parameters, it executes `getDataModel()`, and if there are parameters, it executes the `setDataModel()` method.

### Selection Model - ht.SelectionModel

Using the `List` as an example, during interaction, users may need to select one or more rows in the list. How should these operations be handled?

![list](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lie3fgfhxibd28o0t17t.png)
Here we use `HT`'s selection model `ht.SelectionModel` (referred to as `sm`).

`ht.SelectionModel` manages the selection state of `Data` objects in the `DataModel`. Each `DataModel` object has a built-in `SelectionModel`. Controlling this `SelectionModel` you’ll controls the selection state of all objects bound to the `DataModel`.

You can obtain the selection model 'sm' of a list by using either `dataModel.getSelectionModel()` or `listView.getSelectionModel()`. Once you have obtained the selection model, you can use `sm.getSelection()` and `sm.setSelection(datas)` to respectively retrieve and set the selected state of the Data. For example:

```
const sm = dataModel.getSelectionModel(); // get the selection model of the DataModel
sm.setSelection(data); // select one Data. The premise is that the `Data` has been created and added to the DataModel
```

### View Component

View components are `HTML` elements that are displayed to users and can be used for interaction. For example, tables, 2D displays, and 3D scenes that mentioned earlier. As `HT` encapsulates native `HTML` elements and binds each view component to `DataModel` and `Data`, we only need to modify the properties of `Data` through `JavaScript` code to drive the changes of view components. This logic is basically the same in various view components in `HT`, so it will be very easy in development after familiarizing with this coding logic.

Using 3D scene as an example. The following code will add a 3D scene under the body tag and display the grid lines. After adding the scene, we’ll then add a new `HT` node.

```
const g3d = new ht.graph3d.Graph3dView(); // create a 3D scene
g3d.setGridVisible(true); // show grid on the ground
g3d.addToDOM(); // add the 3D scene to DOM

const dm = g3d.dm(); // get the `DataModel` of the 3D scene

const dataModel = dm;
const sm = dataModel.getSelectionModel(); // get the selection model of the DataModel

let node = new ht.Node(); // create a `HT` node, ht.Node is extended from `ht.Data`
dm.add(node); // add the node to 3D scene
sm.setSelection(node); // select a the node

const p3 = node.getPosition3d(); //default position in 3D scene：[0, 0, 0]
```

![3d scene](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/he605mdik139tzc49nel.png)

The `HT` node (`ht.Node`) is actually a class extended from `ht.Data`. On the `HT` Node, it has richer attribute definitions, such as setting size, scaling, rotation angle, position, and textures. In a 3D scene, each `HT` node can be used to represent a 3D model or other objects. For example, here we did not configure its attributes, so it defaults to displaying a hexahedron.

In the above example, we created a 3D scene view component. Each 3D scene corresponds to a `DataModel`. After obtaining the `DataModel` of the scene, we then added one `ht.Node`. Since no position was specified, the system placed it at the default position of `[0, 0, 0]`;

After following the steps above and creating our own 3D scene with multiple models, we may want to save all the data in the scene for future use. This is where serialization and deserialization come into play.

### Serialization and deserialization

Serialization and deserialization are very important concepts in `HT`. Serialization allows us to convert data in `DataModel` into strings and save them as files. Deserialization can help us restore files to `DataModel`. Since `DataModel` corresponds to view components, this enables us to save and restore our view data.

In `HT`, we can use the `serialize()` and `deserialize()` methods of the `DataModel` to perform serialization and deserialization operations. After serialization, the `DataModel` data will be converted into a `JSON` string.

```
const json = dm.serialize(); // serialization 

dm.deserialize(json); // deserialization 
```

As shown in the example above, the `JSON` string we obtained after serializing the 3D scene is as follows:

```
{
  "v": "7.7.1",
  "p": {
    "autoAdjustIndex": true,
    "hierarchicalRendering": false,
    "postProcessingData": {
      "huesaturation": {
        "hue": [0, 0, 0, 0, 0, 0, 0],
        "saturation": [0, 0, 0, 0, 0, 0, 0],
        "lightness": [0, 0, 0, 0, 0, 0, 0]
      },
      "bloom": {},
      "glitch": {}
    }
  },
  "d": [{
    "c": "ht.Node",
    "i": 6
  }]
}
```

The `JSON` data format used here is a custom format of **Hightopo**. To save storage space, each property uses an abbreviated form. We generally do not need to modify it.

### Summary

This chapter introduces some basic concepts of `HT  for Web`, including: the basic data type `ht.Data`, the data model `ht.DataModel`, the selection model `ht.SelectionModel`, view components, and serialization and deserialization. These concepts are fundamental to `HT  for Web` and are used throughout the development process. Understanding their functions and the logic between them is crucial for subsequent development and understanding of the operation logic of various components in `HT  for Web`.