Comment se faire des amis Electron et Webix. Partie 2. Créez une application avec votre vue

introduction


Dans l' article précédentnous avons examiné avec vous la question de l'intégration du framework Webix dans Electron et de la création d'une application GUI simple basée sur ces frameworks. Le but de cet article est de développer davantage la question de l'intégration dans une interface graphique construite avec l'aide d'Electron et Webix d'autres frameworks JavaScript. Tous les éléments GUI implémentés dans "Webix" sont caractérisés par le paramètre "view". Selon la valeur de ce paramètre, l'un ou l'autre élément GUI sera affiché. Le nombre de types d'éléments "view" qui vous permettent de créer "Webix" chevauchent environ 90% des tâches lors de la mise en œuvre de l'interface. Les 10% restants ne sont que le cas où il est nécessaire d'intégrer soit du code précédemment écrit, soit un framework (bibliothèque) qui n'est pas explicitement pris en charge dans Webix.Pour implémenter l'intégration avec des frameworks tiers (bibliothèques), nous allons créer avec vous notre élément «view» Webix.

Formulation du problème


Créez une application graphique "Electron + Webix", qui va construire un graphique d'une fonction de la forme "y = a * sin (b) + c" avec la possibilité de changer les paramètres de la fonction "a, b et c" avec une redessine dynamique du graphique.

Petite réservation


Faites immédiatement une réservation que dans "Webix" il existe des outils standard très puissants pour travailler avec des graphiques. Mon objectif n'est pas de compléter ces outils, mais de montrer comment vous pouvez intégrer des cadres ou des bibliothèques supplémentaires dans le bundle Electron + Webix. Il se trouve que j'avais un code prêt à l'emploi pour ce graphique en utilisant «D3.js» et j'ai décidé de l'intégrer dans l'application.

Outils


  1. Code Visual Studio - éditeur code.visualstudio.com .
  2. Node.JS - téléchargez ici nodejs.org/en
  3. Electron - installer "npm install --save-dev electron".
  4. Webix – ru.webix.com.
  5. JQuery – «npm jquery»
  6. D3.js – d3js.org
  7. (https://github.com/kapakym/electron_webix) , .


1. Comme je suis paresseux, je ne veux pas écrire tout le code depuis le début pour la deuxième fois. Par conséquent, nous prenons le code de l'article précédent et le remplissons dans le dossier dont nous avons besoin. Il y a deux options. La première consiste simplement à télécharger l'archive à partir du site (Fig. 1) ou à la cloner si vous avez installé le client Git (Fig. 2).


Figure. 1 - Téléchargement du code source depuis un site


Fig. 2 - Clonage du référentiel

2. Afin de ne pas être confondu à l'avenir, renommez le dossier (c'est facultatif), par exemple, comme «electron_webix_2» et ouvrez-le dans Visual Studio Code (Fig. 3).


Figure. 3 - Ouvrez le projet

3. Installez les éléments nécessaires. La première chose que vous devez faire est de télécharger à partir du lien fourni dans les outils ci-dessus "Node.JS" et de l'installer. Sans "Node.JS", vous ne pouvez rien faire de plus. Ensuite, ouvrez la console «Ctr +` »dans Visual Studio Code et entrez les commandes suivantes une par une (Fig. 4):

  • "Npm install --save-dev electron";
  • "Npm install jquery".


Figure. 4 - Installer Node.JS et JQuery

4. Ensuite, vous et moi aurons toujours besoin du framework "D3.js", nous le téléchargeons également en utilisant le lien des outils (fichier "d3.zip"). De l'archive téléchargée «d3.zip», nous extrayons le fichier «d3.js» et le plaçons dans le dossier «libs» (Fig. 5).


Figure. 5 - Ajout de la bibliothèque D3.js

Sur ce poste de travail, nous avons préparé.

Taper l'interface


Maintenant que le lieu de travail est prêt, passons directement à la création de notre application. Il comprendra les éléments de "vue" suivants:

  • - barre d'outils, un élément Webix standard. Cet élément sera placé en haut de la fenêtre et contiendra les boutons de contrôle de la fenêtre et le nom de l'application. Nous avons déjà créé cet élément d'interface dans les matériaux de l'article précédent, et ici nous ne changerons rien;
  • - myview, que vous et moi n'aurons qu'à créer, pour ainsi dire, une «vue» personnalisée. Ce sera la zone dans laquelle le graphe de notre fonction sera construit en utilisant le framework «D3.js». Entre autres choses, cette zone apprendra à s'adapter à la taille de la fenêtre de notre application. Placez-le au milieu de la fenêtre de l'application;
  • - slider, un élément standard de «Webix». Cet élément vous permet de changer sa valeur en utilisant le soi-disant "curseur". Nous allons créer 3 pièces de ces éléments, chacun sera responsable de changer un certain paramètre de notre fonction «a, b ou c». Placez-les au bas de la fenêtre de l'application.

Commençons. Ouvrez le fichier "renderer.js" et modifiez-le ie nous supprimons les éléments dont nous n'avons pas besoin de l'article précédent et les remplaçons par les éléments décrits ci-dessus.

Le fichier «renderer.js» était comme ceci:

//   
const { remote } = require('electron')
//           
let WIN = remote.getCurrentWindow()
//   webix
const webix = require('./libs/webix.min.js')
//  JQuery
$ = require('jquery')
//               
webix.ui(
    {
        "id": 1587908357897,
        "rows": [
            {
                "css": "webix_dark",
                "view": "toolbar",
                "height": 0,
                "cols": [
                    { "view": "label", "label": "Elcetron +Webix its cool!", css:"head_win" },
                    { "label": "-", "view": "button", "height": 38, "width": 40, id:"min-bt" },
                    { "label": "+", "view": "button", "height": 38, "width": 40, id:"max-bt" },
                    { "label": "x", "view": "button", "height": 38, "width": 40, id:"close-bt" }
                ]
            },
            {
                "width": 0,
                "height": 0,
                "cols": [
                    { "url": "demo->5ea58f0e73f4cf00126e3769", "view": "sidebar", "width": 177 },
                    {
                        "width": 0,
                        "height": 0,
                        "rows": [
                            { "template": "Hello WORLD! ", "view": "template" },
                            {
                                "url": "demo->5ea58f0e73f4cf00126e376d",
                                "type": "bar",
                                "xAxis": "#value#",
                                "yAxis": {},
                                "view": "chart"
                            }
                        ]
                    }
                ]
            }
        ]
    }
)

//  
$$("close-bt").attachEvent("onItemClick", () => {
    const window = remote.getCurrentWindow();
    window.close();
})

//  
$$("min-bt").attachEvent("onItemClick", () => {
    const window = remote.getCurrentWindow();
    window.minimize();
})

//  
$$("max-bt").attachEvent("onItemClick", () => {
    const window = remote.getCurrentWindow();
    if (!window.isMaximized()) {
        window.maximize();
    } else {
        window.unmaximize();
    }
})

Cela deviendra comme ceci:

//   
const { remote } = require('electron')
//           
let WIN = remote.getCurrentWindow()
//   webix
const webix = require('./libs/webix.min.js')
//  JQuery
$ = require('jquery')
//               
webix.ui(
    {
        "id": 1587908357897,
        "rows": [
            {
                // view : toolbar - 1   
                "css": "webix_dark",
                "view": "toolbar",
                "height": 0,
                "cols": [
                    //  
                    { "view": "label", "label": "Electron + Webix + D3.js", css:"head_win" },
                    //  " "
                    { "label": "-", "view": "button", "height": 38, "width": 40, id:"min-bt" },
                    //  " "
                    { "label": "+", "view": "button", "height": 38, "width": 40, id:"max-bt" },
                    //  
                    { "label": "x", "view": "button", "height": 38, "width": 40, id:"close-bt" }
                ]
            },
            // view : myview -    ,      .
            { "view": "myview", id: "d3_chart" },
            {
                "cols": [
                    // view : slider - 3 .     sin
                    {
                        "label": "Amplitude", "title": "#value#", "value": 50, "view": "slider", id: "slider_amplitude",
                    },
                    // view : slider - 4 .      sin   Y
                    {
                        "label": "Bias", "title": "#value#", "value": 0, "view": "slider", "height": 38, id: "slider_scope", min:-50, max:50, step:1,
                    },
                    // view : slider - 5 .     sin
                    {
                        "label": "Frequency", "title": "#value#", "value": 0.005, "view": "slider", "height": 38, id: "slider_freq", min:0, max:0.1, step:0.001,
                    }
                ]
            }
        ]
    }
)

//  
$$("close-bt").attachEvent("onItemClick", () => {
    const window = remote.getCurrentWindow();
    window.close();
})

//  
$$("min-bt").attachEvent("onItemClick", () => {
    const window = remote.getCurrentWindow();
    window.minimize();
})

//  
$$("max-bt").attachEvent("onItemClick", () => {
    const window = remote.getCurrentWindow();
    if (!window.isMaximized()) {
        window.maximize();
    } else {
        window.unmaximize();
    }
})

Examinons plus en détail quels paramètres incluent "{" view ":" myview ", id:" d3_chart "}":
- view: myview - tapez "view", alors qu'il n'existe pas, nous ne l'avons pas encore créé;
- id: d3_chart - id "Webix", nous l'utiliserons pour faire référence à notre élément.
Je vais également expliquer les paramètres de l'élément «slider» pour être complet:
- vue: slider - tapez «view», slider;
- étiquette: «texte» - une étiquette qui sera affichée sur le curseur;
- title: "#value" - la valeur actuelle affichée du curseur;
- valeur: «valeur» - valeur du curseur par défaut;
- min: "valeur" - la valeur minimale du curseur;
- max: "valeur" - la valeur maximale du curseur ";
- étape:" valeur "- l'étape de modification de la valeur du curseur.
Vous pouvez en savoir plus sur tous les paramètres des éléments Webix ici docs.webix.com/desktop__components.html

Créer "myview"


Créez maintenant un fichier «view_chart.js» dans lequel nous définissons notre nouveau type «myview» et ouvrez-le dans «VSC».


Figure. 6 - Prise en main de l'édition de view_chart.js

Ajoutez-y le code suivant:

webix.protoUI({
    name: "myview",
    $init: function () {
    },
    redraw: function (a, b, c) {
    },
}, webix.ui.view);

La fonction webix.protoUI est conçue pour créer des éléments Webix personnalisés basés sur des éléments standard. Considérez les paramètres qui sont passés à cette fonction:

  • nom - nom de l'élément créé;
  • $ init est une fonction qui sera lancée lors de la création d'un élément. En d'autres termes, c'est un constructeur;
  • redessiner - notre fonction avec vous, qui sera chargée de redessiner le graphique de la fonction. Nous transmettrons les valeurs des paramètres de nos variables «a, b et c»
  • webix.ui.view est le parent de notre élément.

Vous pouvez en savoir plus sur webix.protoUI ici.
Ainsi, lorsque le cadre de notre «vue» sera prêt, nous écrirons quelques fonctions qui seront chargées de tracer le graphe sin.
La fonction de calcul des valeurs de la fonction sin ressemblera à:
function calcsin(a, b, c) {
    dataset = [];
    for (var i = 1; i < 360; i++) {
        dataset.push({ "x": i, "y": a * Math.sin(b * i) + c });
    };
};


Tout est très simple ici, nous substituons les valeurs des paramètres dans la fonction mathématique sin et enregistrons le résultat dans un tableau. Ajoutez-le à la fin du fichier "view_chart.js".
Ensuite, ajoutez à la fin du fichier «view_chart.js» une fonction qui dessinera un graphique en utilisant le framework D3.js, il ressemblera à ceci:
function drawSin() {
    $(document).ready(function () {
        width = $("#mycontent").width() - margin.left - margin.right
        height = $("#mycontent").height() - margin.top - margin.bottom;
        var xScale = d3.scaleLinear()
            .domain([0, 360]) 
            .range([0, width]); 

        var yScale = d3.scaleLinear()
            .domain([-100, 100]) 
            .range([height, 0]);  

        var line = d3.line()
            .x(function (d, i) { return xScale(d.x); }) 
            .y(function (d) { return yScale(d.y); })
            .curve(d3.curveMonotoneX)

        var svg = d3.select("#mycontent").append("svg")
            .attr("float", "center")
            .attr("class", "webix_chart")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")

        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height/2 + ")")
            .call(d3.axisBottom(xScale)); 

        svg.append("g")
            .attr("class", "y axis")
            .call(d3.axisLeft(yScale))

        svg.append("path")

            .datum(dataset) 
            .attr("class", "line") 
            .attr("d", line); 
    })

}

L'ordre de la fonction donnée est le suivant:
- calculer la taille du graphique par rapport à l'élément div dans lequel il est placé «largeur» et «hauteur»;
- nous mettons à l'échelle les valeurs du graphique par «X» et «Y»;
- créer un élément "html" "svg" dans lequel on trace l'axe "X", l'axe "Y" et le graphe lui-même;
Maintenant que les fonctions de calcul et de rendu de notre graphique sont prêtes, nous allons connecter quelques bibliothèques et déclarer plusieurs variables au début du fichier "view_chart.js":
//     D3.js
const d3 = require("./libs/d3")
//   JQuery
$ = require('jquery')
//          X    Y
var dataset = [];
//         
var margin = { top: 50, right: 50, bottom: 50, left: 50 }
    , width = $("#mycontent").width() - margin.left - margin.right 
    , height = $("#mycontent").height() - margin.top - margin.bottom;

Les variables "largeur" ​​et "hauteur" stockeront la largeur et la hauteur du graphique, en tenant compte de l'indentation.
Ensuite, revenez à la fonction "webix.protoUI" et écrivez sa fonctionnalité:
webix.protoUI({
    name: "myview",
    $init: function () { //  View
        //   div  id=mycontent.      
        this.$view.innerHTML = "<div id='mycontent'></div>"
        //   calcsin       data  
        calcsin(60, 0.05, 0)
        //   drawSin        data
        drawSin()
    },
    redraw: function (a, b, c) { //    
        //   
        $("#mycontent").html("")
        //       data
        calcsin(a, b, c)
        //  
        drawSin()
    },
}, webix.ui.view);

Rempli de contenu deux fonctions. Le premier «init» n'est exécuté qu'une seule fois lors de la création de la «vue». Le second sera appelé lorsque nous devrons redessiner le graphique.
Maintenant, le contenu complet du fichier "view_chart.js" ressemblera à ceci:
//     D3.js
const d3 = require("./libs/d3")
//   JQuery
$ = require('jquery')
//          X    Y
var dataset = [];
//         
var margin = { top: 50, right: 50, bottom: 50, left: 50 }
    , width = $("#mycontent").width() - margin.left - margin.right 
    , height = $("#mycontent").height() - margin.top - margin.bottom;

webix.protoUI({
    name: "myview",
    $init: function () { //  View
        //   div  id=mycontent.      
        this.$view.innerHTML = "<div id='mycontent'></div>"
        //   calcsin       data  
        calcsin(60, 0.05, 0)
        //   drawSin        data
        drawSin()
    },
    redraw: function (a, b, c) { //    
        //   
        $("#mycontent").html("")
        //       data
        calcsin(a, b, c)
        //  
        drawSin()
    },
}, webix.ui.view);



function drawSin() {
    $(document).ready(function () {
        width = $("#mycontent").width() - margin.left - margin.right
        height = $("#mycontent").height() - margin.top - margin.bottom;
        var xScale = d3.scaleLinear()
            .domain([0, 360]) 
            .range([0, width]); 

        var yScale = d3.scaleLinear()
            .domain([-100, 100]) 
            .range([height, 0]);  

        var line = d3.line()
            .x(function (d, i) { return xScale(d.x); }) 
            .y(function (d) { return yScale(d.y); })
            .curve(d3.curveMonotoneX)

        var svg = d3.select("#mycontent").append("svg")
            .attr("float", "center")
            .attr("class", "webix_chart")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")

        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height/2 + ")")
            .call(d3.axisBottom(xScale)); 

        svg.append("g")
            .attr("class", "y axis")
            .call(d3.axisLeft(yScale))

        svg.append("path")

            .datum(dataset) 
            .attr("class", "line") 
            .attr("d", line); 
    })

}

function calcsin(a, b, c) {
    dataset = [];
    for (var i = 1; i < 360; i++) {
        dataset.push({ "x": i, "y": a * Math.sin(b * i) + c });
    };
};


Ensuite, vous devez connecter le contenu du fichier "view_chart.js" dans le fichier "renderer.js". Pourquoi devons-nous ajouter la ligne "require (" ./ view_chart.js ") en haut du fichier renderer.js comme indiqué ci-dessous:
//   
const { remote } = require('electron')
//           
let WIN = remote.getCurrentWindow()
//   webix
const webix = require('./libs/webix.min.js')
//  JQuery
$ = require('jquery')
//  view_chart.js
require("./view_chart.js")


Vous devez maintenant ajouter quelques styles au fichier «styles.css», l'ouvrir et ajouter les styles «svg path» et «#mycontent» comme indiqué ci-dessous:
.head_win {
    -webkit-app-region: drag;
}

/*   */
svg path{
    /*   */
    stroke: #666;
    /*   */
    fill: none;
    /*    */
    stroke-width: 1;
}

/*   mycontent,     */
#mycontent { 
    /*     */
    text-align: center;
    /*   */
    overflow: none;
    /*   */
    border: 1px solid black;
    /*     */
    background-color: antiquewhite;
    /*   */
    height: calc(100% - 2px);
}

Une fois que vous avez terminé avec les styles, vous pouvez essayer d'exécuter notre application et voir ce qui s'est passé. Donc, appuyez sur "F5" et après cela, une fenêtre devrait apparaître sur l'écran comme le montre la figure 7.


Fig. 7 - Fenêtre de notre application

Que voyons-nous dessus? La partie supérieure est la barre d'outils Webix standard. La partie centrale est le graphique que nous avons créé dans myview. La partie inférieure est constituée de trois curseurs que nous devons apprendre à modifier les valeurs des paramètres de notre fonction.

Faisons fonctionner les curseurs


Passons maintenant à l'étape dans laquelle nous allons redessiner le graphique au milieu de notre application, en fonction des valeurs des curseurs «Amplitude», «Biais» et «Fréquence». Pourquoi ajoutons-nous le gestionnaire d'événements «onChange» aux curseurs comme indiqué ci-dessous:

// view : slider - 3 .     sin
                    {
                        "label": "Amplitude", "title": "#value#", "value": 50, "view": "slider", id: "slider_amplitude",
                        on: {
                            onChange: function () {
                                $$("d3_chart").redraw($$("slider_amplitude").getValue(), $$("slider_freq").getValue(), $$("slider_scope").getValue());
                            }
                        }
                    },
                    // view : slider - 4 .      sin   Y
                    {
                        "label": "Bias", "title": "#value#", "value": 0, "view": "slider", "height": 38, id: "slider_scope", min:-50, max:50, step:1,
                        on: {
                            onChange: function () {
                                $$("d3_chart").redraw($$("slider_amplitude").getValue(), $$("slider_freq").getValue(), $$("slider_scope").getValue());
                            }
                        }
                    },
                    // view : slider - 5 .     sin
                    {
                        "label": "Frequency", "title": "#value#", "value": 0.005, "view": "slider", "height": 38, id: "slider_freq", min:0, max:0.1, step:0.001,
                        on: {
                            onChange: function () {
                                $$("d3_chart").redraw($$("slider_amplitude").getValue(), $$("slider_freq").getValue(), $$("slider_scope").getValue());
                            }
                        }
                    }

Dans ce gestionnaire, nous allons accéder à notre élément par son «id» et appeler la fonction «redessiner» que nous avons créée plus tôt pour redessiner le graphique, en lui passant les valeurs actuelles des curseurs. Cliquez sur «F5», exécutez notre application et essayez de modifier les valeurs (Fig. 8).


Figure. 8 - Vérification de la fonctionnalité des curseurs

Tirez le graphique après la fenêtre


Et enfin, nous ajoutons une fonction qui adaptera notre graphique à la taille de la fenêtre lorsqu'elle changera. Pourquoi ouvrons-nous le fichier "view_chart.js" dans l'éditeur et ajoutons un gestionnaire à sa fin qui détecte les modifications de la fenêtre comme indiqué ci-dessous:

window.onresize = function ( e ) {
  
    $("#mycontent").html("")
    drawSin()
}

Cette fonction fonctionne lorsque la fenêtre est redimensionnée. Sa fonctionnalité se résume à effacer le contenu du bloc «mycontent» et à redessiner le graphique (en appelant la fonction «drawSin ()»). Chaque fois que la fonction drawSin () est appelée, les variables largeur et hauteur reçoivent les informations actuelles sur les tailles (hauteur et largeur) du bloc mycontent, après quoi le graphique modifie l'échelle pour s'adapter aux dimensions du bloc.

Conclusion


C'est tout. J'espère que ces informations vous seront utiles. Remercier! Les sources peuvent être téléchargées ici .

All Articles