preface

Before on the Internet to see other people write about the periodic table, and deeply aroused a wave of memories, memories of junior high school period back “hydrogen, helium, lithium beryllium, boron, carbon and nitrogen oxygen fluorine neon, magnesium, sodium aluminum silicon phosphorus, sulfur, chlorine argon potassium calcium”, “keep (oxygen) turtle (silicon), aluminum iron cover (ca), which was (sodium (potassium)) didn’t (mg) and green (hydrogen) vegetables (ti)”, In high school, I remember the conservation of mass, the conservation of elements, the conservation of atoms, and the conservation of electrons. Time flies, and we are already so big.

Now I’m using HT to implement it. HT has 2D topology and 3D model scene. I’ve implemented both forms.

The interface display

The whole page is composed of HT UI components, which use HT. UI.TabLayout TAB components to display 23D interfaces.

2D interface: The whole is a HT.ui. SplitLayout partition component (split left and right), the left side uses HT.Ui. HTView to wrap the GraphView topology component, and the right side is an HT.Ui. Form component.

3D interface: The whole is a HT.ui.SplitLayout split component (top and bottom), add hT.ui.HBoxLayout button group on the top, and wrap the Graph3dView scene with HT.ui.

The demo address: www.hightopo.com/demo/elemen…

2D interface code analysis

Topology components

Ht.graph. GraphView is the component with the most abundant 2D functions in HT framework. It has the functions of presenting and editing basic graphics, connecting topological nodes and automatic layout, predefined objects in electric power and telecommunication industries, and special effects such as animation rendering, so it has a wide range of applications. It can be used as a mapping tool and human-machine interface in the field of monitoring, as a general graphical editing tool, and can be extended to workflow and organization chart and other enterprise applications.

The 118 elements displayed in the topology are all HT. Node topology nodes. The default Node display is a small computer style. Here we use setImage to set the image information displayed on the Node, as shown below:

A vector diagram describes a graph with points, lines, and polygons, so it can be zoomed in and out with consistent accuracy. The figure above is a vector map, composed of 1 rectangle and 6 text, arbitrary scaling without distortion, you can visit the demo address, through the wheel to scale topology for experience, specific vector map drawing please refer to the vector manual.

I’m sure some of you are wondering, with 118 elements, if you want to draw 118 vectors, it feels a little bit acceptable, but if it’s tens of thousands, you’ll be exhausted. HT helped us solve this problem by binding the data of the drawn vector graph and binding the properties of the drawn content to the properties of the node. By updating the corresponding properties of the node in the application, the graphical interface will be refreshed automatically to achieve the effect of real-time data display, such as my vector graph. A (‘background’, ‘#FEB64D’) to change the background color of the rectangle. For details about data binding, see the data binding manual.

While we’re on the subject of data binding, let’s take a look at the ability to display the classification of elements. Compare this to the following image, where the node style changes not by re-setimage another vector, but by changing the binding style properties of the original vector. According to the category of the element, modify the rectangle background color of the vector graph and the text color of the element’s Chinese name. Ht.ui. ToggleButton switch button, with “0/1” state switch, by monitoring whether the button is selected, to switch the periodic table style.

 1 toggle.on('p:selected', e => {
 2     if (e.newValue) {
 3         this.htView.legend.s('2d.visible'.true); / / display category 4 this legend. HtView. AddClassification (); // display category 5} 6else {
 7         this.htView.legend.s('2d.visible'.false); // Hide category Figure 8 this.htview.initElements (); // Original style 9} 10});Copy the code

The element category legend is also an HT. Node Node, which is also a vector drawn, and is present in the drawing from the beginning. Node.s (‘2d.visible’, false) is set to invisible and true is used to show the category.

The form panel

The form panel on the right has six rows, and the second one is a radio button for periodic table display and rotation display to switch between display effects.

The third line is the above mentioned display classification function, the fourth line is a text input box, used to obtain the ordinal number of elements, limited to the input number, but also increased the input number of verification, can only input 1~118.

The code is as follows:

 1 let textField = new ht.ui.TextField();
 2 textField.setFormDataName('textField'); // Set the name in the form 3 textField.setplaceholder ('Please enter the ordinal number of elements to query! '); 4 textField.setMaskRe(/\d/); Textfield.setinstant ();true); TextField. On ('p:value', (e) => {// Listen for value change event 7let value = e.newValue;
 8     if (value > 118) {
 9         textField.setErrorMessage('Only elements 1 to 118! ', {
10             placements: ['top'11]}); 12} 13else{ textField.setErrorMessage(null); }});Copy the code

Line 5 is a text field hT.ui.textarea that displays the element information for the query.

Line 6 is a set of buttons to submit query data and reset form information.

3D interface code analysis

Button group

Ht.ui.HBoxLayout horizontal layout, hBox added 4 buttons for 3D shape conversion.

Button support icon and text, provide normal, hover, active, disabled four states, button generation code:

 1 createButton(text) {
 2     let button = new ht.ui.Button();
 3     button.setBorder(null);
 4     button.setHoverBorder(null);
 5     button.setActiveBorder(null);
 6     button.setBackground(new ht.ui.drawable.ColorDrawable('rgba (37115194,0.6)', 4)); 7 button. / / normal background setHoverBackground (new ht. UI. Drawable. ColorDrawable ('rgba (10,92,173,0.50)', 4)); / / hover background 8 button. SetActiveBackground (new ht. UI. Drawable. ColorDrawable ('rgba (15132250,0.6)', 4)); // Active background 9 button.settext (text); 10 button.setTextColor('rgb(0, 211, 255)');
11     button.setHoverTextColor('rgb(0, 211, 255)');
12     button.setActiveTextColor('rgb(0, 211, 255)'); 13 to 14returnbutton; 15}Copy the code

Listen for click events with button.on(‘click’, e => {// toggle function}).

The 3 d scene

Ht.graph3d. Graph3dView, through the encapsulation of the underlying technology of WebGL, drives the graphics display based on the unified DataModel DataModel of ht as well as other components of ht, greatly reducing the threshold of 3D graphics technology development. On the basis of being familiar with HT data model, the average programmer only needs 1 hour to learn 3D graphics development.

The element is displayed as a face in the 3D scene, and the vector map is made for the face in 2D. The display style is also controlled by modifying the node attributes.

1 node.s({
2     'shape3d': 'billboard'// Set the node type to "Billboard" bulletin board 3'shape3d.image': 'symbols/element (2) the json'// Set the face map to 4'shape3d.reverse.flip': true// Set whether positive content is displayed on the back 5'shape3d.image.cache': true// Map cache 6'shape3d.fixSizeOnScreen': false, // Set whether to keep the screen size fixed and not change with zooming 7'select.brightness': 1 // set brightness to 1 8});Copy the code

The dm is a DataModel, or bound data container, and a datasMap is used to store the position of elements before and after changes for animation-driven use.

1. Random shuffle: set a set of spatial range values and generate random values (x,y,z) within the range to set node positions.

 1 let dm = this.dm,
 2     datasMap = {};
 3 
 4 dm.each(data => {
 5     letx = Math.random() * 2000 - 1000; // Get random x 6lety = Math.random() * 2000 - 1000; // get random y 7letz = Math.random() * 500 - 250; // get random z 8 9letposition = data.getPosition3d(), 10 px = position[0], 11 py = position[1], 12 pz = position[2]; 13 14 datasMap[data] = { 15 x: x, 16 y: y, 17 z: z, 18 px: px, 19 py: py, 20 pz: pz 21 }; 22});Copy the code

2. Spherical surround: firstly calculate and obtain spherical coordinates, and then convert them into spatial rectangular coordinates according to the rules.

 1 letdm = this.elements, 2 datasMap = {}; 3, 4,letr = 500, 5 phi, theta; 6, 7for (let i = 0; i < 118; i++) { 
 8     letdata = dm.get(117 - i); 9 phi = Math.acos(-1 + (2 * i ) / 118); 10 theta = Math.sqrt(118 * Math.PI) * phi; 11 to 12letz = r * Math.sin(phi) * Math.cos(theta), 13 x = r * Math.sin(phi) * Math.sin(theta), 14 y = r * Math.cos(phi); 15 to 16letposition = data.getPosition3d(), 17 px = position[0], 18 py = position[1], 19 pz = position[2]; 20 21 datasMap[data] = { 22 x: x, 23 y: y, 24 z: z, 25 px: px, 26 py: py, 27 pz: pz 28 }; 29}Copy the code

3. Ring around: Set a ring radius and start height, rotate at a fixed Angle, and lower the setting height of the node each time.

 1 let dm = this.dm,
 2     datasMap = {},
 3     datas = dm.getDatas(),
 4     radius = 400,
 5     angle = 18,
 6     num = 360 / angle;
 7 
 8 let y = 300, 
 9     count = 0;
10 for (let i = 0; i < 6; i++) {
11     for (let j = 0; j < num; j++) {
12         letdata = datas.get(count), 13 radian = Math.PI / 180 * j * angle; 14 and 15if(! data)break;
16         count++;
17 
18         let x = radius * Math.cos(radian),
19             z = radius * Math.sin(radian); 
20         
21         letposition = data.p3(), 22 px = position[0], 23 py = position[1], 24 pz = position[2]; 25 26 datasMap[data] = { 27 x: x, 28 y: y, 29 z: z, 30 px: px, 31 py: py, 32 pz: pz 33 }; 34 y -= 6; 35}} 36Copy the code

4. Restoration: Calculate the xy value of the element node according to the number of rows and columns of the recorded element, and the z value is fixed.

 1 let dm = this.dm,
 2     datasMap = {};
 3 
 4 dm.each(data => {
 5     let index = data.a('index'),
 6         row = data.a('row'),
 7         col = data.a('col'); 8 and 9letposition = data.getPosition3d(), 10 px = position[0], 11 py = position[1], 12 pz = position[2]; 13 14 datasMap[data] = { 15 index: index, 16 row: row, 17 col: col, 18 px: px, 19 py: py, 20 pz: pz 21 }; 22});Copy the code

Finally, there is an element style switch. In the upper right corner is an HT.ui. HBoxLayout landscape layout. Three HT.ui. Label child components are added to achieve this effect by limiting the width of the HBox to the width of the Label. Styles are changed by listening on the label under the wheel event.

conclusion

Looking at the periodic table again, do you remember the chemical equations on the blackboard in chemistry class? Do you remember the burning of the alcohol lamp in chemistry experiment class? Do you still remember the operation process of the experiment and the correct placement of the instruments?

To operate again: www.hightopo.com/demo/chemis…