aardio 文档

aardio 范例: 画曲线

import win.ui;
/*DSG{{*/
var winform = win.form(text="画曲线";right=746;bottom=469)
winform.add(
edit={cls="edit";left=102;top=322;right=703;bottom=352;edge=1;multiline=1;z=2};
canvas={cls="canvas";left=32;top=25;right=703;bottom=302;bgcolor=0xFFFFFF;anchors={left=1;top=1;right=1;bottom=1};z=1};
static={cls="static";text="增长率:";left=32;top=365;right=94;bottom=385;align="right";transparent=1;z=5};
static2={cls="static";text="拐点:";left=32;top=400;right=94;bottom=420;align="right";transparent=1;z=6};
trackbarGrowth={cls="plus";left=102;top=367;right=703;bottom=382;bgcolor=0x23ABD9;border={radius=-1};color=0x005CFF;anchors={right=1;bottom=1};foreRight=15;forecolor=0xFF771C;paddingBottom=5;paddingTop=5;z=3};
trackbarMidpoint={cls="plus";left=102;top=407;right=703;bottom=422;bgcolor=0x23ABD9;border={radius=-1};color=0x005CFF;anchors={right=1;bottom=1};foreRight=15;forecolor=0xFF771C;paddingBottom=5;paddingTop=5;z=4}
)
/*}}*/

//曲线数据与两个数值标签
var curve = {coordinates = {}};

//绘图资源只创建一次,标签字体用逻辑像素,绘图时随 DPI 缩放
var labelFont = gdip.font("Segoe UI",13);
var labelBrush = gdip.solidBrush(0xFF333333);
var borderPen = gdip.pen(0xFF808080,1);
var rightFormat = gdip.stringFormat();
rightFormat.align = 2/*_StringAlignmentFar*/;
var centerFormat = gdip.stringFormat();
centerFormat.align = 1/*_StringAlignmentCenter*/;
centerFormat.lineAlign = 1/*_StringAlignmentCenter*/;

//更新绘图数据
var updateCurve = function(calc,xMin,xMax,xStep,yMax){

        var width,height = winform.canvas.width,winform.canvas.height;
        if(!yMax) yMax = calc(xMax,yMax);

        var scaleX = width / (xMax - xMin);  
        var scaleY = height / yMax;

        var coordinates = [];
        for(x = xMin; xMax; xStep){ 

            //转换为画布坐标(设备像素)
            ..table.push(
                coordinates,(x - xMin) * scaleX, 
                height - (calc(x,yMax) * scaleY) );
        }

        curve.coordinates = coordinates;
        curve.maxText = math.stringify( calc(xMax,yMax),2 );
        curve.sampleText = math.stringify( calc(10168,yMax),2 );
}

//绘图事件
winform.canvas.onDrawForeground = function(graphics,rc){
    var dpiX,dpiY = winform.dpiScale(1,1);

    var coordinates = curve.coordinates;
    if(#coordinates){
        var pen = gdip.pen(0xFFFF0000, 2*dpiX);  

        /*
        注意 coordinates 至少包含 3 个坐标点才能画出曲线,如果仅 2 个坐标点只能画出直线

        coordinates 支持两种格式的数组
        - [x1,y1,x2,y2,...] // 也就是数值数组,每两个数值表示一个坐标点
        - [{float x;float y},{float x;float y},...] //也就是 POINTF 结构体数组
        */
        graphics.drawCurve(pen, coordinates);
        pen.delete();
    }

    //边框与数值标签用逻辑坐标绘制
    var saved = graphics.save();
    graphics.scale(dpiX,dpiY);
    var width,height = rc.width/dpiX,rc.height/dpiY;

    graphics.drawRect(borderPen,0.5,0.5,width-1,height-1);
    if(curve.maxText) graphics.drawString(curve.maxText,labelFont,::RECTF(0,10,width-100,24),rightFormat,labelBrush);
    if(curve.sampleText) graphics.drawString(curve.sampleText,labelFont,::RECTF(0,0,width,height),centerFormat,labelBrush);

    graphics.restore(saved);
}

//滑块变动时重新计算曲线坐标
var onPosChanged = function(pos, triggeredByUser){

    var growthRate = winform.trackbarGrowth.progressPos / 100000.0;
    var midpoint = winform.trackbarMidpoint.progressPos / 100.0 * 121759;

    updateCurve(
        lambda (xValue,yMax) yMax / (1 + math.exp(-growthRate * (xValue - midpoint))),
        1/*xMin*/,100000/*xMax*/,1000/*xStep*/,25000
    );

    winform.canvas.redraw();

    winform.edit.text = `增长率: ` + string.format('%.5f', growthRate) 
                + ' 拐点: ' + math.round(midpoint);
}

// 初始化新增的滑块
winform.trackbarGrowth.setTrackbarRange(1, 100);
winform.trackbarGrowth.progressPos = 10; // 默认值
winform.trackbarGrowth.onPosChanged = onPosChanged; // 联动更新

winform.trackbarMidpoint.setTrackbarRange(1, 100);
winform.trackbarMidpoint.progressPos = 30; // 默认值
winform.trackbarMidpoint.onPosChanged = onPosChanged; // 联动更新

//控件大小改变时重新计算坐标
winform.canvas.adjust = function(){
    onPosChanged();
}

winform.onDestroy = function(){
    labelFont.delete();
    labelBrush.delete();
    borderPen.delete();
    rightFormat.delete();
    centerFormat.delete();
}

winform.show();
win.loopMessage();
Markdown 格式