Wie man Freunde findet Electron und Webix. Teil 2. Erstellen Sie eine Anwendung mit Ihrer Ansicht

Einführung


Im vorherigen ArtikelWir haben mit Ihnen das Problem der Integration des Webix-Frameworks in Electron und der Erstellung einer einfachen GUI-Anwendung auf der Grundlage dieser Frameworks untersucht. Der Zweck dieses Artikels ist es, das Problem der Integration in eine GUI-Schnittstelle, die mit Hilfe von Electron und Webix anderer JavaScript-Frameworks erstellt wurde, weiterzuentwickeln. Alle in "Webix" implementierten GUI-Elemente sind durch den Parameter "view" gekennzeichnet. Abhängig vom Wert dieses Parameters wird das eine oder andere GUI-Element angezeigt. Die Anzahl der Arten von "Ansicht" -Elementen, mit denen Sie "Webix" erstellen können, überlappt etwa 90% der Aufgaben bei der Implementierung der Schnittstelle. Die restlichen 10% sind nur dann der Fall, wenn entweder zuvor geschriebener Code oder ein Framework (eine Bibliothek) integriert werden müssen, die in Webix nicht explizit unterstützt werden.Um die Integration in Frameworks (Bibliotheken) von Drittanbietern zu implementieren, erstellen wir zusammen mit Ihnen unser Webix-Element "view".

Formulierung des Problems


Erstellen Sie eine GUI-Anwendung „Electron + Webix“, die ein Diagramm einer Funktion der Form „y = a * sin (b) + c“ mit der Möglichkeit erstellt, die Parameter der Funktion „a, b und c“ mit einem dynamischen Neuzeichnen des Diagramms zu ändern.

Kleine Reservierung


Machen Sie sofort einen Vorbehalt, dass es in "Webix" standardmäßige, sehr leistungsfähige Tools für die Arbeit mit Diagrammen gibt. Mein Ziel ist es nicht, diese Tools zu ergänzen, sondern zu zeigen, wie Sie zusätzliche Frameworks oder Bibliotheken in das Electron + Webix-Bundle integrieren können. Es ist einfach so passiert, dass ich mit „D3.js“ einen vorgefertigten Code für dieses Diagramm hatte und mich entschied, ihn in die Anwendung zu integrieren.

Werkzeuge


  1. Visual Studio Code - Editor code.visualstudio.com .
  2. Node.JS - hier herunterladen nodejs.org/en
  3. Electron - installiere "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. Da ich faul bin, möchte ich nicht zum zweiten Mal den gesamten Code von Anfang an schreiben. Daher nehmen wir den Code aus dem vorherigen Artikel und füllen ihn in den Ordner, den wir benötigen. Es gibt zwei Möglichkeiten. Das erste ist nur, das Archiv von der Site herunterzuladen (Abb. 1) oder es zu klonen, wenn Sie den Git-Client installiert haben (Abb. 2).


Feige. 1 - Herunterladen des Quellcodes von einer Site


Abb. 2 - Klonen des Repositorys

2. Um später nicht verwirrt zu werden, benennen Sie den Ordner um (dies ist optional), z. B. "Electron_webix_2", und öffnen Sie ihn in Visual Studio Code (Abb. 3).


Feige. 3 - Öffnen Sie das Projekt

3. Installieren Sie die erforderlichen Elemente. Das erste, was Sie tun müssen, ist, den Link in den Tools über „Node.JS“ herunterzuladen und zu installieren. Ohne "Node.JS" können Sie nichts weiter tun. Öffnen Sie als Nächstes die Konsole „Strg +` “in Visual Studio Code und geben Sie nacheinander die folgenden Befehle ein (Abb. 4):

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


Feige. 4 - Installation von Node.JS und JQuery

4. Als Nächstes benötigen Sie und ich weiterhin das Framework "D3.js". Wir laden es auch über den Link aus den Tools herunter (Datei "d3.zip"). Aus dem heruntergeladenen Archiv „d3.zip“ extrahieren wir die Datei „d3.js“ und legen sie im Ordner „libs“ ab (Abb. 5).


Feige. 5 - Hinzufügen der D3.js-Bibliothek

An dieser Workstation haben wir vorbereitet.

Eingabe der Schnittstelle


Nachdem der Arbeitsplatz vorbereitet ist, können Sie direkt mit der Erstellung unserer Anwendung fortfahren. Es besteht aus den folgenden "Ansicht" -Elementen:

  • - Symbolleiste, ein Standard-Webix-Element. Dieses Element wird oben im Fenster platziert und enthält die Fenstersteuerungsschaltflächen und den Namen der Anwendung. Wir haben dieses Schnittstellenelement bereits in den Materialien des vorherigen Artikels erstellt, und hier werden wir nichts ändern.
  • - myview, das Sie und ich sozusagen nur erstellen müssen, um eine benutzerdefinierte „Ansicht“ zu erstellen. In diesem Bereich wird der Graph unserer Funktion mit dem Framework „D3.js“ erstellt. In diesem Bereich wird unter anderem gelernt, sich an die Größe des Fensters unserer Anwendung anzupassen. Platzieren Sie es in der Mitte des Anwendungsfensters.
  • - Schieberegler, ein Standardelement von „Webix“. Mit diesem Element können Sie seinen Wert mit dem sogenannten "Schieberegler" ändern. Wir werden 3 Teile solcher Elemente erstellen, von denen jedes für die Änderung eines bestimmten Parameters unserer Funktion „a, b oder c“ verantwortlich ist. Platzieren Sie sie am unteren Rand des Anwendungsfensters.

Lass uns anfangen. Öffnen Sie die Datei "renderer.js" und bearbeiten Sie sie dh Wir entfernen die Elemente, die wir nicht benötigen, aus dem vorherigen Artikel und ersetzen sie durch die oben beschriebenen Elemente.

Die Datei "renderer.js" sah folgendermaßen aus:

//   
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();
    }
})

Es wird so werden:

//   
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();
    }
})

Lassen Sie uns genauer betrachten, welche Parameter "{" view ":" myview ", id:" d3_chart "}" enthalten:
- view: myview - type "view", obwohl es nicht existiert, haben wir es noch nicht erstellt;
- id: d3_chart - "Webix" -ID, wir werden sie verwenden, um auf unser Element zu verweisen.
Der Vollständigkeit halber werde ich auch die Parameter des Elements "Schieberegler" erläutern:
- Ansicht: Schieberegler - Typ "Ansicht", Schieberegler;
- Beschriftung: „Text“ - eine Beschriftung, die auf dem Schieberegler angezeigt wird;
- title: "#value" - der aktuell angezeigte Wert des Schiebereglers;
- Wert: "Wert" - Standard-Schiebereglerwert;
- min: "Wert" - der Mindestwert des Schiebereglers;
- max: "Wert" - der Maximalwert des Schiebereglers ";
- Schritt:" Wert "- der Schritt zum Ändern des Werts des Schiebereglers.
Weitere Informationen zu allen Parametern von Webix-Elementen finden Sie hier docs.webix.com/desktop__components.html

Erstellen Sie "myview"


Erstellen Sie nun eine Datei "view_chart.js", in der wir unseren neuen Typ "myview" definieren und in "VSC" öffnen.


Feige. 6 - Erste Schritte zum Bearbeiten von view_chart.js

Fügen Sie den folgenden Code hinzu:

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

Die Funktion webix.protoUI dient zum Erstellen benutzerdefinierter Webix-Elemente basierend auf Standardelementen. Betrachten Sie die Parameter, die an diese Funktion übergeben werden:

  • name - Name des erstellten Elements;
  • $ init ist eine Funktion, die beim Erstellen eines Elements gestartet wird. Mit anderen Worten, es ist ein Konstruktor;
  • Neu zeichnen - unsere Funktion mit Ihnen, die für das Neuzeichnen des Diagramms der Funktion verantwortlich ist. Wir werden die Werte der Parameter unserer Variablen "a, b und c" weitergeben.
  • webix.ui.view ist das übergeordnete Element unseres Elements.

Weitere Informationen zu webix.protoUI finden Sie hier.
Wenn der Rahmen unserer „Ansicht“ fertig ist, werden wir einige Funktionen schreiben, die für das Zeichnen des Sin-Graphen verantwortlich sind.
Die Funktion zur Berechnung der Werte der sin-Funktion sieht folgendermaßen aus:
function calcsin(a, b, c) {
    dataset = [];
    for (var i = 1; i < 360; i++) {
        dataset.push({ "x": i, "y": a * Math.sin(b * i) + c });
    };
};


Hier ist alles sehr einfach, wir setzen die Parameterwerte in die mathematische Funktion sin ein und speichern das Ergebnis in einem Array. Fügen Sie es am Ende der Datei "view_chart.js" hinzu.
Fügen Sie als Nächstes am Ende der Datei "view_chart.js" eine Funktion hinzu, die mithilfe des D3.js-Frameworks ein Diagramm zeichnet. Es sieht folgendermaßen aus:
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); 
    })

}

Die Reihenfolge der angegebenen Funktion ist wie folgt:
- Berechnen Sie die Größe des Diagramms relativ zu dem div-Element, in das es "Breite" und "Höhe" gepackt ist;
- Wir skalieren die Werte des Graphen mit „X“ und „Y“.
- Erstellen Sie ein "HTML" -Element "svg", in dem wir die "X" -Achse, die "Y" -Achse und den Graphen selbst zeichnen.
Nachdem die Funktionen zum Berechnen und Rendern unseres Diagramms bereit sind, verbinden wir einige Bibliotheken und deklarieren mehrere Variablen am Anfang der Datei "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;

Die Variablen "width" und "height" speichern die Breite und Höhe des Diagramms unter Berücksichtigung der Einrückung.
Gehen Sie als nächstes zurück zur Funktion "webix.protoUI" und schreiben Sie deren Funktionalität:
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);

Gefüllt mit Inhalt zwei Funktionen. Der erste "Init" wird beim Erstellen der "Ansicht" nur einmal ausgeführt. Die zweite wird aufgerufen, wenn wir das Diagramm neu zeichnen müssen.
Nun sieht der vollständige Inhalt der Datei "view_chart.js" folgendermaßen aus:
//     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 });
    };
};


Als nächstes müssen Sie den Inhalt der Datei "view_chart.js" in der Datei "renderer.js" verbinden. Warum müssen wir die Zeile "require (" ./ view_chart.js ") oben in die Datei renderer.js einfügen, wie unten gezeigt:
//   
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")


Jetzt müssen Sie der Datei "styles.css" einige Stile hinzufügen, sie öffnen und die Stile "svg path" und "#mycontent" wie unten gezeigt hinzufügen:
.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);
}

Nachdem Sie mit den Stilen fertig sind, können Sie versuchen, unsere Anwendung auszuführen und zu sehen, was passiert ist. Drücken Sie also „F5“ und danach sollte ein Fenster auf dem Bildschirm angezeigt werden (siehe Abbildung 7)


. 7 - Fenster unserer Anwendung

Was sehen wir darauf? Der obere Teil ist die Standard-Webix-Symbolleiste. Der mittlere Teil ist das Diagramm, das wir in myview erstellt haben. Der untere Teil besteht aus drei Schiebereglern, die wir lernen müssen, um die Werte der Parameter unserer Funktion zu ändern.

Lassen Sie die Schieberegler funktionieren


Fahren wir nun mit dem Schritt fort, in dem wir das Diagramm in der Mitte unserer Anwendung neu zeichnen, abhängig von den Werten der Schieberegler „Amplitude“, „Bias“ und „Frequency“. Warum fügen wir den Schiebereglern den Ereignishandler "onChange" hinzu, wie unten gezeigt:

// 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());
                            }
                        }
                    }

In diesem Handler greifen wir über die ID auf unser Element zu und rufen die zuvor erstellte Funktion "Neu zeichnen" auf, um das Diagramm neu zu zeichnen, wobei wir die aktuellen Werte der Schieberegler übergeben. Klicken Sie auf „F5“, führen Sie unsere Anwendung aus und versuchen Sie, die Werte zu ändern (Abb. 8).


Feige. 8 - Überprüfen der Funktionalität der Schieberegler

Ziehen Sie die Grafik nach dem Fenster


Und schließlich fügen wir eine Funktion hinzu, die unser Diagramm an die Größe des Fensters anpasst, wenn es sich ändert. Warum öffnen wir die Datei "view_chart.js" im Editor und fügen am Ende einen Handler hinzu, der Fensteränderungen wie unten gezeigt abfängt:

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

Diese Funktion funktioniert, wenn die Fenstergröße geändert wird. Seine Funktionalität besteht darin, den Inhalt des Blocks "mycontent" zu löschen und das Diagramm neu zu zeichnen (Aufruf der Funktion "drawSin ()"). Bei jedem Aufruf der Funktion drawSin () werden den Variablen width und height die aktuellen Informationen zu den Größen (Höhe und Breite) des mycontent-Blocks zugewiesen. Anschließend ändert das Diagramm den Maßstab, um ihn an die Blockabmessungen anzupassen.

Fazit


Das ist alles. Ich hoffe, diese Informationen werden Ihnen nützlich sein. Danke! Quellen können hier heruntergeladen werden .

All Articles