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

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u012814856/article/details/79700560

一、引言

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

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

饼图 Gif

想要了解如何实现 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 示例中修改代码的情况:

ECharts

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

那么,除了要显示之外,我们还想要达到可以对饼图百分之百的控制。这也就是说,我们可以随时修改饼图的数据,并让其即时刷新。这也是引言中 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:)

展开阅读全文

没有更多推荐了,返回首页