欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在 Soui 中嵌入 MiniBlink 初体验(三):实现一个界面友好动态可交互的饼图

程序员文章站 2022-07-01 12:42:13
...

一、引言

在上周,我已经调研了在下 Soui 中嵌入 MiniBlink 浏览器控件,并且使用百度的开源可视化库 ECharts 显示图表的可行性。

这篇博客,让我们来实现一个简单的界面友好的、动态可交互的饼图显示。最后的效果图如下:

在 Soui 中嵌入 MiniBlink 初体验(三):实现一个界面友好动态可交互的饼图

想要了解如何实现 Soui 中 MiniBlink 浏览器控件的嵌入的同学,可以点击这里:
在 Soui 中嵌入 MiniBlink 初体验(一):支持百度 ECharts 开源可视化库显示

如果在使用 ECharts 库出现了程序显示不出来,但是浏览器却可以的问题,可以点击这里:
在 Soui 中嵌入 MiniBlink 初体验(二):解决本地 Html 文件显示 ECharts 失败的问题

想要查看本篇博客代码的网友,可以点击这里:
wangying2016/ECharts-In-Soui

好,接下来,我们开始吧!

二、ECharts 在线编写 Demo

我们要实现一个饼图的显示,必然要先写 ECharts 的显示代码。

其实这个也简单,即使是像我这样对于 js 不是很了解的人也可以轻松上手。新入门 ECharts 的同学可以看看 ECharts 的教程文档,还是很容易上手的:
ECharts 教程文档

这里,我为了实现一个饼图,在 ECharts 实例中在线进行了修改,并查到了其修改饼图元素名称、值和颜色的方法(教程里有说到,可以直接看代码),写出代码如下:

app.title = '环形图';

option = {
    tooltip: {
        trigger: 'item',
        formatter: "{a} <br/>{b}: {c} ({d}%)"
    },
    legend: {
        orient: 'vertical',
        x: 'left',
        data:['五杀','四杀','三杀','送成鬼']
    },
    series: [
        {
            name:'成绩分布',
            type:'pie',
            radius: ['50%', '70%'],
            avoidLabelOverlap: false,
            label: {
                normal: {
                    show: false,
                    position: 'center'
                },
                emphasis: {
                    show: true,
                    textStyle: {
                        fontSize: '30',
                        fontWeight: 'bold'
                    }
                }
            },
            labelLine: {
                normal: {
                    show: false
                }
            },
            data:[
                {value:1, name:'五杀',itemStyle:{color:'#26d7bc'}},
                {value:1, name:'四杀',itemStyle:{color:'#24bdee'}},
                {value:1, name:'三杀',itemStyle:{color:'#ffdb83'}},
                {value:1, name:'送成鬼',itemStyle:{color:'#ff8181'}}
            ]
        }
    ]
};

至此,我们显示一个界面友好的饼图的任务就完成了一半了。下图是在 ECharts 示例中修改代码的情况:

在 Soui 中嵌入 MiniBlink 初体验(三):实现一个界面友好动态可交互的饼图

三、实现动态交互:怎么能让饼图数据即时刷新显示?

那么,除了要显示之外,我们还想要达到可以对饼图百分之百的控制。这也就是说,我们可以随时修改饼图的数据,并让其即时刷新。这也是引言中 Gif 的效果。

怎么做呢?

通过我的调研,发现我们可以使用这么一种思路:

我们可以这么实现饼图数据的即时刷新:
1. 在 js 代码中声明一个全局的数组,让其记录各个项目的数值
2. 写一个 js 函数,让其设置各个项目的数值并且重绘界面
3. 在 C++ 的层面,使用 C++ 调用我们在上一步中写的 js 函数,从而完成数据的设置和界面的即时刷新

思路很清晰,让我们看看具体是怎么做的:

1. 首先,我们声明一个全局的数组,记录需要的数值:

// 我们定义的全局数组,用来存储饼图各个项目的数值
var values = new Array(1,1,1,1);
...
// 这是具体设置饼图显示数据的地方,使用数组取值的方法
 data: [
                            { value: values[0], name: '五杀', itemStyle: { color: '#26d7bc' } },
                            { value: values[1], name: '四杀', itemStyle: { color: '#24bdee' } },
                            { value: values[2], name: '三杀', itemStyle: { color: '#ffdb83' } },
                            { value: values[3], name: '送成鬼', itemStyle: { color: '#ff8181' } }
                        ]

2. 然后,我们写两个函数,一个是 showPie(),用来显示饼图,一个是 changeValue(),用来设置数据并且再次显示饼图

这是我们的 changeValue 函数,注意它包含两个逻辑,一个是修改值,另一个则还需要重新绘制饼图的逻辑。

function changeValue(value1, value2, value3, value4) {
    values[0] = value1;
    values[1] = value2;
    values[2] = value3;
    values[3] = value4;
    // alert("开始修改数据,并且让 ECharts 显示");
    showPie();
}

这是我们的 showPie() 函数,这个函数在两个地方调用,一次是在打开载入 html 界面中全局调用一次,另一次则就是上面那个 changeValue() 函数中调用一次:

function showPie() {
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'));

    var option = {
        tooltip: {
            trigger: 'item',
            formatter: "{a} <br/>{b}: {c} ({d}%)"
        },
        legend: {
            orient: 'vertical',
            x: 'left',
            data: ['五杀', '四杀', '三杀', '送成鬼']
        },
        series: [
            {
                name: '成绩分布',
                type: 'pie',
                radius: ['50%', '70%'],
                avoidLabelOverlap: false,
                label: {
                    normal: {
                        show: false,
                        position: 'center'
                    },
                    emphasis: {
                        show: true,
                        textStyle: {
                            fontSize: '30',
                            fontWeight: 'bold'
                        }
                    }
                },
                labelLine: {
                    normal: {
                        show: false
                    }
                },
                data: [
                    { value: values[0], name: '五杀', itemStyle: { color: '#26d7bc' } },
                    { value: values[1], name: '四杀', itemStyle: { color: '#24bdee' } },
                    { value: values[2], name: '三杀', itemStyle: { color: '#ffdb83' } },
                    { value: values[3], name: '送成鬼', itemStyle: { color: '#ff8181' } }
                ]
            }
        ]
    };

    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);
}

3. 最后,我们只需要使用 C++ 代码调用上面那个 changeValue() js 函数即可。这里我添加了四个按钮,分别对应了饼图的四个项目,每点击一次,则默认增加一个单位值,用以测试饼图的动态显示。在这里,最核心的代码就是 C++ 调用 changeValue() 的代码了:

// 调用 js 函数 ChangeValue
HRESULT CMainDlg::_CallJsChangeValue(UINT uValue1, UINT uValue2, UINT uValue3, UINT uValue4)
{
    SOUI::SWkeWebkit *pWkeWebkit = FindChildByName2<SOUI::SWkeWebkit>(L"wke_test");
    if (pWkeWebkit != NULL) {
        SOUI::SStringA strCallJs;
        strCallJs.Format("changeValue(%d,%d,%d,%d);", uValue1, uValue2, uValue3, uValue4);
        wkeRunJS(pWkeWebkit->GetWebView(), strCallJs);
    }
    return S_OK;
}

看到上述代码的 SOUI::SStringA 不要害怕,这是 Soui 特有的字符串类型,使用 MiniBlink 调用 js 的函数是 wkeRunJS,这个函数还是很方便使用的,第一个参数需要传一个 wkeWebKit 类型的对象,第二个参数就是我们的 js 代码。这里我将 changeValue 的调用形式进行了可变参数匹配,用来适配多种类型的调用。

注:这里需要着重注意的是,在 MiniBlink 中,想要处理 wkeRunJS 函数调用 js 函数返回的值,需要手动添加一个 return,按照作者的说法,是为了兼容 V8 而必须加上 return,如果不加上 return ,则获取不到 js 函数的返回值:

...
// 调用方式类似
jsValue jsRet = wkeRunJS(pWkeWebkit->GetWebView(), "return getValue();");
...

这里为了处理 getValue() js 函数的返回值,需要手动加个 return。

至此,我们已经完成了这个非常有成就感的 Demo!

完结,撒花 ^_^

四、总结

这篇博客是前两篇博客的实际的探索,实现了我在一开始想要实现的效果。毕竟以需求为导向,总是能够驱动着自己去探索更多东西。

MiniBlink 真是个好玩的东西,另外,ECharts 也是一个非常强大的可视化库,也非常好玩。有时间一定还要继续深钻。

明天还要继续~~~

To be Stronger:)