Public Documentation
  • Introduction
  • Getting started
    • Introduction
    • 1. Welcome Page
    • 2. Introduction (Beginner's Guide)
  • Portal Tools
    • Blocko
      • Ůvod do blocka
      • Flip-flop
      • REST-API bloček
    • Grid
      • Úvod do GRID
      • Základní Tlačítko (základy GRID)
      • vylepšený Přepínač (stylování a pokročilé možnosti GRID)
      • text generátor button (messeage type, two elements one widget)
      • graf (pokročilé funkce GRID)
      • Slider (User class v GRIDu)
      • Styly a jejich použití
  • Cloud
    • Cloud
    • Instancies
    • Rest-Api
  • General
    • What we plan
  • Hardware a programování
    • Úvod
      • Nahrání prvního programu
    • Konektivita
      • Specifikace zdroje internetu
      • GSM
      • 6LowPAN
      • Komunikace s portálem
      • Přepínání mezi servery
    • Hardware
      • Základní jednotky
        • IODAG3E
          • Rozhraní a periférie
          • Konektor X a Y
          • Napájení
          • Připojení zdroje k VBAT
          • Paměti
          • Technické specifikace
          • Schémata
        • IODAG3L
      • Rozšiřující moduly
        • GSM shield
        • LED shield
        • Relay shield
        • RFID shield
        • Ultrasonic shield
        • Meteo shield
        • Movement shield
        • PIR shield
        • RGB Displej shield
        • Serial shield
      • Ostatní
        • DevKitG3
          • Schéma
        • TK3G
          • Schéma
        • ZPPG3
          • Schéma
        • WEXP
    • Programování HW
      • Architektura FW
        • Aktualizace FW
        • Autobackup
      • Struktura programu
      • Byzance API
        • Vstupy a výstupy do Portálu
        • Callback Busy
        • Odložený restart
        • Callbacky připojení
        • Uživatelská makra
      • MBED API
        • Vstupy a výstupy
        • Komunikační rozhraní
        • Časování
        • RTOS
      • Knihovny
        • DHT
        • DS1820
        • Dali
        • EdgeStruct
        • I2CWrapper
        • Knock
        • MFRC522
        • MFRC522::MIFARE_Key
        • MPU9150
        • ms5637
        • OneWire
        • PCA9536
        • RGB_matrix
        • RollerDrive
        • SHT21
        • ST7565
        • Servo
        • TCA6424A
        • TLC59116
        • TripleSevenSeg
        • MFRC522::Uid
        • WS2812
        • WakeUp
      • Offline programování
        • Vlastní IDE
        • Upload kódu z GUI
        • Upload kódu z konzole
        • Upload kódu Drag&drop
    • Tutoriály
      • Datum a čas (RTC)
      • Komunikace po sériové lince (UART) s PC
        • Konfigurace sériové linky v PC
        • Programování sériové linky
      • Základní tutoriály
        • Digital Read
        • Analog Read/Write
        • PWM Fade
        • Timer/Ticker
        • State Change Detection
        • Ovládání LED modulu
        • BusOut
        • HC-SR04 Senzor
      • Pokročilé
    • Správa a diagnostika
      • Zdroj restartu
      • LED modul
      • Identifikace zařízení
      • Monitoring parametrů
      • Vytížení zařízení
      • Webové rozhraní
        • Základní přehled
        • Správce firmware
        • Vlákna
        • Definované vstupy
        • Konfigurace MQTT
        • Nastavení
      • Bootloader
        • Režimy bootloaderu
        • Command mód
        • Další vlastnosti bootloaderu
      • Webová konzole
      • Konfigurace zařízení
        • Confighash
      • Omezení konfigurace
        • Konfigurace
        • Binárky
        • Omezení MQTT
        • Lowpan
    • Knowledge base
      • Náhodná čísla
      • Watchdog
      • Paměť RAM
Powered by GitBook
On this page
  • Úvodní kód:
  • uchování hodnot:
  • Event render a kreslení
  • více práce s kreslením
  • zakreslování hodnot
  • překreslení hodnot (re-render)
  • Vodící čáry grafu:
  • změna četnosti vykreslování
  • konečné slovo:
  1. Portal Tools
  2. Grid

graf (pokročilé funkce GRID)

Previoustext generátor button (messeage type, two elements one widget)NextSlider (User class v GRIDu)

Last updated 7 years ago

Založíme si nový projekt a pojmenujeme si LineGraph.

Úvodní kód:

vytvoříme Analogový vstup. Analog je reprezontován (desetiným) číslem. které může jít i do záporných hodnot. (Poslední datový typ messeage, si ukážeme později.)

let anaIn = context.inputs.add("analin","analog","Analog Input");

a přidáme sizeProfile

context.addSizeProfiles(3,2,20,20);

a nakonec přidáme "generický element", na kterém budeme pracovat.

let element = new WK.Element(context);

Tímto jsme si vytvořili bílý obdélník jenž vyplňuje celou plochu widgetu.

uchování hodnot:

Určitě budeme chtít zaznamenat hodnoty, které pak vykreslíme do widgetu jako graf. Proto si vytvoříme pole., do kterého si budeme ukládat hodnoty. (připomínám, že pole v Javascriptu(typescriptu) fungují jinak než v Javě,C(++/#) apod.)

let dataStorage = [];

Nejlepší způsob, jak získat hodnotu z inputu je event listenerem. Proto napíšem

anaIn.listenEvent("valueChanged", e => {        
    dataStorage.push(anaIn.value);      
});

Pozn.: kvůli bugu v GRID se nová hodnota nedá získat z callbacku (e).

tímto při každé změně uložíme novou hodnotu do pole.

Nyní je třeba začít s vykreslováním na element.

Event render a kreslení

Veškeré vykreslování se děje v

context.listenEvent("render", e => {        
    let draw = e.context;    
})

čímž kreslíme na vrh celé "plochy" widgetu. Protože budeme hodně používat e.context, uložil jsem si ho do promněné pro jednodušší práci.

Ve zkratce nyní shrnu nejduležitější body z dokumentace Canvasu,

  • Prakticky veškeré úkony s ním začínáme tím, že zavoláme metodu .beginPath();

  • bod 0,0 se nachází v levém horním rohu

  • veškeré změny projeví až poté co zavoláme .stroke();

Nakreslíme si základní testovací čáru. pod námi definovaný _draw _napíšeme

draw.beginPath();  
 draw.moveTo(0,0);  
 draw.lineTo(context.root.visibleRect.size.width,context.root.visibleRect.size.height);  
 draw.strokeStyle = "#000000";  
 draw.stroke();`

a klikneme na test

Čára by vždy měla být z levého horního rohu do dolního pravého. Pozornější si jistě všimli context.root.invalidate();Tato metoda se volá kdykoliv se změní widget a je třeba znovu ho celý vykreslit (znova zavolá render). Např. při změně velikosti widgetu, nebo když ho zavoláme my s tím že chceme vykreslit nově příchozí hodnoty.

když už jsme dali dohromady základy práce s canvasem, jsem si udělat graf z hodnot co ukládáme do pole.

více práce s kreslením

Pro snažší práci si zabarvíme pozadí na bílo a vytvoříme si několik promněných pro snažší práci.

Samozřejmě, přídáme si element, který jsme vytvořili na žačátku do widgetu. context.root.add(element);

nyní by při kliknuntí na test měla čára být nakreslená na bílém pozadí.

Na začátek renderu si nadefinujeme několik pomocných promněných.

začneme s

let chartPaddingX = 10;  
let chartPaddingY = 10;

chceme nechat nějaký prostor na krajích. poté

let chartX = 30 + chartPaddingX;  
let chartY = 10 + chartPaddingY;

jakožto "startovací bod" pro náš graf (vlevo nahoře). Odtud budeme začínat se vším vykreslováním.

nakonec

let chartWidth = context.root.visibleRect.size.width - chartPaddingX  
let chartHeight = context.root.visibleRect.size.height - chartPaddingY;

Ve zkratce jsme si nadefinovali výšku a šířku pro náš widget, složením těchto dvou hodnot máme souřadnice pravého dolního rohu našeho grafu. U _chartWidth _jsme si vzali šířku celého widgetu (která může být různě veliká) a odečetli jsme od ní padding (pro odstup od okraje).

Abychom zhruba věděli, jak je náš Graf ve widgetu velký, změníme několik parametrů v naší předtím vytvořené čáry.

změníme

draw.moveTo(0,0);  
 draw.lineTo(context.root.visibleRect.size.width,context.root.visibleRect.size.height);

na

 draw.moveTo(chartX, chartY);  
 draw.lineTo(chartWidth, chartHeight);

klikneme na test a podíváme se, zda se všechno povedlo dle plánu.

zakreslování hodnot

Poté, co jsme si oveřili že vše vypadá OK, mohli bychom získat data z našeho pole, a zakreslit je do widgetu. to uděláme smyčkou(loop).

nejdříve najdeme nejvyšší hodnotu v poli, což uděláme jednoduše:

let max = 0;  
    for (let i = 0; i < dataStorage.length; i++) {  
        if (max < dataStorage[i]) {  
            max = dataStorage[i];  
        }  
    }

vytvoříme promněnou, kterou budeme určovat počet prvků jenž zobrazíme v grafu

let chartSize = 50;

poté napíšeme smyčku na vykreslování grafu jako takového:

render.beginPath();
let first = true;  
    for (let i = Math.max(dataStorage.length - chartSize, 0), j = 0; i < dataStorage.length; i++ , j++) {  
        const x = chartX + (j / chartSize) * chartWidth;  
        const y = chartY + chartHeight - (dataStorage[i] / max) * chartHeight;
        if (first) {
             draw.moveTo(x, y);
         } 
        else { 
             draw.lineTo(x, y);
         }
    first = false;    
    }
draw.strokeStyle = "#489fdf";  
draw.stroke();`

překreslení hodnot (re-render)

To nejdůležitější je hotovo. Pokud jste ještě nedopsali to, že při změně hodnoty se má překreslit widget, nyní je správná chvíle

anaIn.listenEvent("valueChanged", e => {
    context.root.invalidate();
    dataStorage.push(anaIn.value);
});

`

a můžeme náš widget otestovat.

widget by měl při každé změně hodnoty nakreslit nový graf, který se postupně posouvá.

Vodící čáry grafu:

Avšak, graf bez hodnot je užitečný jako bezdrátová myš bez baterek. Přidáme text a "vodící čáry'

draw.fillStyle = "#000";
draw.fillText("0", 3, chartY + chartHeight - 3);
draw.fillText(max, 3, chartY + 13);
draw.strokeStyle = "rgba(0,0,0,0.5)";

draw.beginPath();
draw.moveTo(chartX, chartY);
draw.lineTo(chartX + chartWidth, chartY);
draw.stroke();

draw.beginPath();
draw.moveTo(chartX, chartY + chartHeight);
draw.lineTo(chartX + chartWidth, chartY + chartHeight);
draw.stroke();

Zároveň, můžeme přidat i to, že se vykreslí "kolečka" na vrcholech. první část kódu známe

 for(let i = Math.max(dataStorage.length - chartSize, 0), j = 0; i < dataStorage.length; i++, j++) {
        const x = chartX + (j / chartSize) * chartWidth;
        const y = chartY + chartHeight - (dataStorage[i] / max) * chartHeight;
        draw.beginPath();
        draw.arc(x,y,2,0,2*Math.PI); //nakreslí oblouk o poloměru Pí * 2 radiánů (celý kruh)
        draw.closePath();
        draw.strokeStyle = "rgb(0, 153, 255)";
        draw.stroke();
        draw.fillStyle = "rgba(0, 153, 255, 0.5)";
        draw.fill();
    }

změna četnosti vykreslování

Pokud se zamyslíme tak zjistíme, že se hodnoty do grafu vykreslují ve chvíli, kdy se změní hodnota vstupu, což je poněkud k ničemu.

Vytvoříme si interval, který bude pravidělně číst a zapisovat do grafu:

setInterval(function () {
    dataStorage.push(input.value); //přidáme hodnotu do pole
    context.root.invalidate(); //překreslíme widget
}, 1000);

a listener smažeme, protože nechceme nadále zapisovat hodnoty pouze při změně, ale pravidelně

input.listenEvent("valueChanged", function (e) {});

výsledný graf bude vypadat nějak takto

Pokud jste s grafem spokojeni. Můžete ho vesele používat kde potřebujete.

konečné slovo:

Samozřejmě je zde hromada místa k zlepšení, jako např. možnost ukazovat více čar, možnost zobrazovat i čísla pod nulu...

Widgety vykreslovány v Canvasu, díky tomu můžeme použít oficiální dokumentaci Canvasu.

(LINK).