UI设计了一个气泡词云,没有现成的组件,该怎么实现呢?

3,479 阅读2分钟

背景

我们常见的词云图是这样的

image.png

ui灵机一动(拍脑袋)设计了这样的词云样式,气泡越大表示词的热度越高。没有现成的组件,该怎么实现呢?

image.png

通过查文档发现echarts关系图,如下图所示。外观和我们的要实现的气泡词云有一点像。是否可以基于echarts关系图,通过设置属性来实现气泡词云。 image.png

关键属性设置

{
    type: 'graph',//用于展现节点以及节点之间的关系数据。
    layout: 'force',//采用力引导布局
    force: {
        repulsion: 60,//节点之间的斥力因子。
        edgeLength: 10//两个节点之间的距离
    },
    data: {
        name: node.label,//节点名字
        symbolSize: node.size*1.5,//节点大小
        itemStyle: {//节点的颜色,边框大小,边框颜色
          color: bgcolor,
          borderColor: color,
          borderWidth: node.size/20,//边框大小需要根据标签权值动态调整
        },
        label: {//标签显示属性,标签颜色/标签字体大小
            show: true,
            fontSize: node.size/4,//,标签大小需要根据标签权值动态调整
            color: '#fff',
        },
    }
}

示例展示

将代码复制到echarts调试工具运行,可以查看实现效果。

image.png

var rindex = () => parseInt(Math.random() * 100) % 7;
var mycolor = () => ['#0239bf', '#3cd272', '#f7b500', '#eac900', '#00d0ff', '#00b4c0', '#2c9d68'][rindex()];
var backgroundColor = () => ['rgba(2,57,191, 0.4)', 'rgba(60,210,114, 0.4)', 'rgba(247,181,0,0.4)', 'rgba(234,201,0,0.4)', 'rgba(0,208,255,0.4)', 'rgba(0,180,192,0.4)', 'rgba(44,157,104,0.4)'][rindex()]

myChart.showLoading();
$.getJSON(
  ROOT_PATH + '/data/asset/data/npmdepgraph.min10.json',
  function (json) {
    myChart.hideLoading();
    myChart.setOption(
      (option = {
        animationDurationUpdate: 1500,
        animationEasingUpdate: 'quinticInOut',
        series: [
          {
            layout: 'force',
            force: {
                repulsion: 60,
                edgeLength: 10
            },
            type: 'graph',
            // progressiveThreshold: 700,
            data: json.nodes.filter(item => item.size > 15).map(function (node) {
              let color = mycolor();
              let bgcolor = backgroundColor();
              return {
                id: node.id,
                name: node.label,
                symbolSize: node.size*1.5,
                itemStyle: {
                  color: bgcolor,
                  borderColor: color,
                  borderWidth: node.size/20,
                },
                label: {
                    show: true,
                    fontSize: node.size/4,
                    color: '#fff',
                },
              };
            }),
            zoom: 1,
            center: ['50%', '50%'],
            roam: true,
            edgeSymbol: ['circle', 'arrow'],
          }
        ]
      }),
      true
    );
  }
);