ai

Stencil.js กับ Machine Learning Pipeline —

Stencil.js กับ Machine Learning Pipeline —

Stencil.js สำหรับ ML Dashboard

Stencil.js กับ Machine Learning Pipeline —

Stencil.js เป็น Compiler สร้าง Web Components ใช้ได้ทุก Framework TypeScript JSX Native Web Components ขนาดเล็ก Performance สูง

เนื้อหาเกี่ยวข้อง — บทความที่เกี่ยวข้อง: LLM Fine-tuning LoRA MLOps Workflow —

ML Pipeline Dashboard ต้องการ Components แสดง Model Metrics, Training Progress, Prediction Results ใช้ Stencil.js สร้าง Reusable Components

เนื้อหาเกี่ยวข้อง — ทำความเข้าใจ Prometheus PromQL Scaling Strategy วิธี Scale — คู่มือฉบับสมบูรณ์ 2026

Stencil.js Component Development

// === Stencil.js ML Dashboard Components ===
// npm init stencil
// เลือก component

// 1. ML Metric Card Component
// src/components/ml-metric-card/ml-metric-card.tsx

import { Component, Prop, h, State, Watch } from '@stencil/core';

@Component({
  tag: 'ml-metric-card',
  styleUrl: 'ml-metric-card.css',
  shadow: true,
})
export class MlMetricCard {
  @Prop() metricName: string = '';
  @Prop() metricValue: number = 0;
  @Prop() unit: string = '';
  @Prop() trend: 'up' | 'down' | 'stable' = 'stable';
  @Prop() threshold: number = 0;
  @State() isAlert: boolean = false;

  @Watch('metricValue')
  handleValueChange(newValue: number) {
    this.isAlert = this.threshold > 0 && newValue < this.threshold;
  }

  componentWillLoad() {
    this.handleValueChange(this.metricValue);
  }

  private getTrendIcon(): string {
    switch (this.trend) {
      case 'up': return '▲';
      case 'down': return '▼';
      default: return '●';
    }
  }

  private getTrendColor(): string {
    switch (this.trend) {
      case 'up': return '#22c55e';
      case 'down': return '#ef4444';
      default: return '#6b7280';
    }
  }

  render() {
    return (
      
{this.metricName}
{this.metricValue.toFixed(4)} {this.unit}
{this.getTrendIcon()} {this.trend}
); } } // 2. Training Progress Component // src/components/ml-training-progress/ml-training-progress.tsx @Component({ tag: 'ml-training-progress', styleUrl: 'ml-training-progress.css', shadow: true, }) export class MlTrainingProgress { @Prop() currentEpoch: number = 0; @Prop() totalEpochs: number = 100; @Prop() loss: number = 0; @Prop() accuracy: number = 0; @Prop() status: 'training' | 'completed' | 'failed' = 'training'; private getProgressPercent(): number { return (this.currentEpoch / this.totalEpochs) * 100; } render() { const percent = this.getProgressPercent(); return (
Training Progress {this.status}
Epoch: {this.currentEpoch}/{this.totalEpochs} Loss: {this.loss.toFixed(4)} Accuracy: {(this.accuracy * 100).toFixed(1)}%
); } } // 3. Prediction Result Component @Component({ tag: 'ml-prediction', shadow: true, }) export class MlPrediction { @Prop() predictions: string = '[]'; // JSON string @State() parsedPredictions: Array<{label: string, confidence: number}> = []; componentWillLoad() { try { this.parsedPredictions = JSON.parse(this.predictions); } catch (e) { this.parsedPredictions = []; } } render() { return (

Predictions

{this.parsedPredictions.map(pred => (
{pred.label}
{(pred.confidence * 100).toFixed(1)}%
))}
); } } console.log("Stencil.js ML Components:"); console.log(" ml-metric-card: แสดง Metric พร้อม Trend"); console.log(" ml-training-progress: Training Progress Bar"); console.log(" ml-prediction: Prediction Results");

ML Model Integration

Stencil.js กับ Machine Learning Pipeline —
# ml_api_server.py — FastAPI ML Model Server
# pip install fastapi uvicorn scikit-learn numpy

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import List, Dict, Optional
from datetime import datetime
import numpy as np

app = FastAPI(title="ML Pipeline API")

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"],
)

# Models
class PredictionRequest(BaseModel):
    features: List[float]
    model_name: str = "default"

class PredictionResponse(BaseModel):
    predictions: List[Dict[str, float]]
    model_name: str
    latency_ms: float

class TrainingStatus(BaseModel):
    model_name: str
    current_epoch: int
    total_epochs: int
    loss: float
    accuracy: float
    status: str  # training, completed, failed

class ModelMetrics(BaseModel):
    model_name: str
    accuracy: float
    precision: float
    recall: float
    f1_score: float
    latency_p50_ms: float
    latency_p99_ms: float
    predictions_today: int

# In-memory state
training_status = TrainingStatus(
    model_name="image-classifier-v2",
    current_epoch=75, total_epochs=100,
    loss=0.0823, accuracy=0.9456,
    status="training",
)

@app.get("/api/metrics", response_model=ModelMetrics)
async def get_metrics():
    """Get Model Metrics สำหรับ Dashboard"""
    return ModelMetrics(
        model_name="image-classifier-v2",
        accuracy=0.9456,
        precision=0.9312,
        recall=0.9589,
        f1_score=0.9449,
        latency_p50_ms=12.5,
        latency_p99_ms=45.2,
        predictions_today=15234,
    )

@app.get("/api/training/status", response_model=TrainingStatus)
async def get_training_status():
    """Get Training Status"""
    return training_status

@app.post("/api/predict", response_model=PredictionResponse)
async def predict(request: PredictionRequest):
    """Run Prediction"""
    start = datetime.now()

    # Simulated prediction
    np.random.seed(42)
    labels = ["cat", "dog", "bird", "fish"]
    confidences = np.random.dirichlet(np.ones(len(labels)))

    predictions = [
        {"label": label, "confidence": float(conf)}
        for label, conf in sorted(
            zip(labels, confidences),
            key=lambda x: x[1], reverse=True
        )
    ]

    latency = (datetime.now() - start).total_seconds() * 1000

    return PredictionResponse(
        predictions=predictions,
        model_name=request.model_name,
        latency_ms=latency,
    )

@app.get("/api/pipeline/status")
async def pipeline_status():
    """Pipeline Status Overview"""
    return {
        "stages": [
            {"name": "Data Ingestion", "status": "completed", "records": 50000},
            {"name": "Feature Engineering", "status": "completed", "features": 128},
            {"name": "Model Training", "status": "running", "epoch": 75},
            {"name": "Evaluation", "status": "pending"},
            {"name": "Deployment", "status": "pending"},
        ],
        "last_updated": datetime.now().isoformat(),
    }

# uvicorn ml_api_server:app --host 0.0.0.0 --port 8000

print("ML API Server:")
print("  GET  /api/metrics          - Model Metrics")
print("  GET  /api/training/status  - Training Status")
print("  POST /api/predict          - Run Prediction")
print("  GET  /api/pipeline/status  - Pipeline Overview")

Dashboard Integration



 -->

// Stencil.js Build Commands
// npm run build          — Production build
// npm run generate       — Generate new component
// npm run test           — Run tests
// npm run test.watch     — Watch mode

// stencil.config.ts
// import { Config } from '@stencil/core';
// export const config: Config = {
//   namespace: 'ml-components',
//   outputTargets: [
//     { type: 'dist', esmLoaderPath: '../loader' },
//     { type: 'dist-custom-elements' },
//     { type: 'www', serviceWorker: null },
//   ],
// };

console.log("Dashboard Integration:");
console.log("  Components: ml-metric-card, ml-training-progress, ml-prediction");
console.log("  API: FastAPI ML Server");
console.log("  Update: Auto-refresh every 5s");

Best Practices

  • Shadow DOM: ใช้ Shadow DOM แยก CSS ป้องกัน Style Leaking
  • Props: ใช้ Primitive Types สำหรับ Props (string, number, boolean)
  • Lazy Loading: ใช้ Stencil Lazy Loading โหลด Components ที่ต้องใช้
  • API Integration: ใช้ REST API เชื่อมกับ ML Model Server
  • Real-time: ใช้ WebSocket สำหรับ Real-time Updates
  • Testing: เขียน Unit Tests สำหรับ Components ด้วย Jest

Stencil.js คืออะไร

Compiler สร้าง Web Components ใช้ได้ทุก Framework React Angular Vue Ionic TypeScript JSX Native Web Components ขนาดเล็ก Performance สูง

แนะนำเพิ่มเติม — ติดตาม XM Signal

เนื้อหาเกี่ยวข้อง — อ่านต่อ: Embedding Model Remote Work Setup

XM Legend · เทรดเดอร์ & ผู้สอน Forex 13 ปี

ผู้ก่อตั้ง SiamCafe ตั้งแต่ปี 1997 · เทรดเดอร์สาย Forex มากกว่า 13 ปี ได้รับการยกย่องเป็น XM Legend · แบ่งปันความรู้ Forex, ไอที, AI และการเทรด จากประสบการณ์จริงในตลาดจริง