ECharts4.0数据可视化

绘图需求:SVG 和 Canvas

基于SVG和Canvas,百度推出了Echarts图形库。

(更多api用法可查看官网文档)


浏览器绘图原理:

编写的前端代码最终都将经过浏览器渲染成一个页面。浏览器绘图通过HTML,还可以通过Canvas和SVG的方式来绘图。实际上,HTML、CSS实际都是针对浏览器绘图做出一些指令。

(关于SVG和Canvas的具体用法,可查看我的其他博文)

canvas绘图:通过canvas创建的画布内容允许自己去对内容绘制。

canvas只创建,内容需要我们填充:

canvas这些中的元素是无法被选中的,和dom不同。如果做canvas动画就需要不停的刷新canvas画布。

canvas在很多语言和编程方向中道理都是一致的,例如android中的canvas和flutter等:

SVG绘图:表示矢量绘图。

通过html标签进行绘图。canvas绘图无法被选中。SVG绘制的可以被选中。

放大图,canvas会有锯齿失真,而SVG不会。

Canvas更适合做高性能的动画渲染,Echarts支持canvas和svg。

为了减少canvas失真,一般:

  • 开启抗锯齿
  • 对图形的分辨率做的更大一些,然后对其进行缩放

Echarts:

可以解析为canvas和svg版本。

1.简单的案例体验:

引入后编写代码:

 

 

Echarts+Webpack:

然后就可以使用webpack命令了:

现在报错是因为还没创建webpack配置文件:

引入echarts:

然后

 直接引用模块化是错误的,需要使用webpack构建,引用构建后的源码:

 然后修改引入:

 

常见Echarts图表:

可查看官网,相当丰富


实操:ECharts4实现数据报表组件(vue)

 

APP.vue:

<template>
  <div id="app">
    <sales-report></sales-report>
  </div>
</template>

<script>
import SalesReport from '@/components/SalesReport'
export default {
  name: 'App',
  components: {
    SalesReport,
  }
}
</script>

<style>
  html, body {
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
    background: #eee;
  }
  #app {
    width: 100%;
    height: 100%;
    padding: 20px;
    box-sizing: border-box;
  }
</style>

index.vue:

<template>
    <div class="language-report">
        <div class="header">编程语言hot榜</div>
        <div class="content">
            <div class="content-title-wrapper">月增长率</div>
            <div class="content-index-wrapper">
                <span class="arrow-star">
                    <svg width="100" height="100" viewBox="0 0 190 180"  
                    fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M95 0L117.227 68.4073H189.155L130.964 110.685L153.191 179.093L95 136.815L36.8093 179.093L59.0361 110.685L0.845406 68.4073H72.7731L95 0Z" fill="#f1c40f"/>
                    </svg>
                </span>
                <span class="percentage">98<span>%</span></span>
                <span class="text">+99,999</span>
            </div>
            <div id="content-chart"/>
            <div class="content-circle-wrapper">
                <div 
                :class="['circle', selectedIndex === index ? 'selected' : '']" 
                @click="change(index)"
                v-for="(item,index) in circle" 
                :key="index"/>
            </div>
            <div class="content-bottom-wrapper">编程语言流行趋势</div>
        </div>
        <div class="footer">
            <div class="footer-wrapper">
                <div class="left">
                    <div class="footer-title">Go使用人数</div>
                    <div class="footer-sub-title">5月累计人数</div>
                </div>
                <div class="right">
                    <small>人</small> 300,254,00
                </div>
            </div>
            <div class="progress-wrapper">
                <div class="progress-bg">
                    <div class="progress-current" :style="{width:`${progress*100}%`}"></div>
                </div>
            </div>
            <div class="footer-text">
                <div>人数增长率</div>
                <div>89%</div>
            </div>
        </div>
    </div>
</template>
<script>
import ECharts from 'echarts';
export default {
    data() {
        return {
            circle: new Array(3),
            selectedIndex: 0,
            progress: 0.75,
        }
    },
    methods: {
        change(index) {
            this.selectedIndex = index;
            this.genChart();
        },
        genChart() {
            // 获取数据源
            const mockData = [];
            for (let i=0;i<10;i++){
               mockData.push(Math.floor( Math.random() * 100) + 200)
            }
            // 获取chart对应的dom
            const chartDom = document.getElementById('content-chart')
            // 初始化echarts对象
            const chart = ECharts.init(chartDom)
            // 渲染参数
            const options = {
                xAxis: {
                    type: 'category',
                    show: false,
                },
                yAxis: {
                    show: false,
                    min: 0,
                    max: 400,
                },
                series: [{
                    data: mockData,
                    type: 'line',
                    smooth: true,
                    areaStyle: {
                        color: '#1abc9c'
                    },
                    lineStyle: {
                        width: 4,
                        color: '#2ecc71'
                    },
                    itemStyle: {
                        borderWidth: 8,
                        color: '#3498db'
                    }
                }],
                grid: {
                    top: 0,
                    bottom: 0,
                    right: -30,
                    left: -30,
                },
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'cross',
                        label: {
                            backgroundColor: '#6a7985'
                        }
                    }
                }
            }
            // 渲染图表
            chart.setOption(options)
        },
    },
    mounted() {
            this.genChart();
            this.task = setInterval(() => {
                let index = this.selectedIndex
                index++
                if(index > this.circle.length){
                    index = 0;
                }
                this.change(index)//
            }, 3000);
    },
    destroyed() {
        if(this.task){
            clearInterval(this.task)
        }
    },
}
</script>
<style lang="scss">
    .language-report {
        display: flex;
        flex-direction: column;
        width: 100%;
        height: 100%;
        background: #fff;
        box-shadow: 0 2px 8px rgba(4,9,20,.3),0 2px 8px rgba(4,9,20,.3),0 2px 8px rgba(4,9,20,.3),0 2px 8px rgba(4,9,20,.3);
        .header {
            width: 100%;
            height: 50px;
            background: orange;
            border-bottom: 2px solid #eee;
            box-sizing: border-box;
            color: rgba(13,27,62,.7);
            padding-left: 20px;
            display: flex;
            align-items: center;
            font-weight: bold;
            color: #fff;
        }
        .content {
            flex: 1;
            width: 100%;
            padding: 0 28px;
            box-sizing: border-box;
            display: flex;
            flex-direction: column;
            .content-title-wrapper {
                padding-top: 28px;
                color: #1abc9c;
                font-size: 13px;
                font-weight: bold;
            }
            .content-index-wrapper {
                display: flex;
                align-items: center;
                .arrow-star {
                    svg {
                        width: 25px;
                    }
                }
                .percentage {
                    font-size: 35px;
                    font-weight: 700;
                    color: #333;
                    margin-left: 15px;
                    span {
                        font-size: 28px;
                        font-weight: 400;
                        color: #999;
                        margin-left: 2px;
                    }
                }
                .text {
                    margin-left: 15px;
                    color: #1abc9c;
                    font-weight:bold;
                }
            }
            #content-chart {
                flex: 1;
                width: 100%;
            }
            .content-circle-wrapper {
                display: flex;
                align-items: center;
                justify-content: center;
                margin-top: 20px;
                .circle {
                    width: 10px;
                    height: 10px;
                    background: #fff;
                    border: 3px solid #3498db;
                    border-radius: 50%;
                    margin: 0 5px;
                    &.selected {
                        background: #3498db;
                    }
                }
            }
            .content-bottom-wrapper {
                margin: 10px 0;
                color: #999;

            }

        }
        .footer {
            display: flex;
            flex-direction: column;
            width: 100%;
            height: 120px;
            border-top: 2px solid #eee;
            box-sizing: border-box;
            .footer-wrapper{
                display: flex;
                padding: 14px 14px 0;
                .left {
                    .footer-title {
                        font-size: 13px;
                        font-weight: 700;
                        color: #333;
                    }
                    .footer-sub-title {
                        font-size: 13px;
                        font-weight: 400;
                        color: #999;
                    }
                }
                .right {
                    flex: 1;
                    text-align: right;
                    color: #1abc9c;
                    font-size: 25px;
                    font-weight: 700;
                    small {
                        font-weight: 400;
                    }
                }
            }
            .progress-wrapper {
                flex: 1;
                display: flex;
                justify-content: center;
                align-items: center;
                padding: 14px;
                .progress-bg {
                    position: relative;
                    width: 100%;
                    height: 7px;
                    background: #95a5a6;
                    border-radius: 3px;
                    .progress-current {
                        position: absolute;
                        left: 0;
                        top: 0;
                        height: 7px;
                        background: #3498db;
                        border-radius: 3.5px;
                        &::after {
                            content: '';
                            position: absolute;
                            top: 0;
                            left: 0;
                            right: 0;
                            bottom: 0;
                            width: 100%;
                            background: #fff;
                            opacity: 0;
                            animation: progress-active 2s ease infinite
                        }
                        @keyframes progress-active {
                            from {
                                width: 0;
                                opacity: 0;
                            }
                            to {
                                width: 100%;
                                opacity: .3;
                            }
                        }
                    }
                }
            }
            .footer-text {
                display: flex;
                justify-content: space-between;
                padding: 0 14px 14px;
                font-size: 13px;
                color: #999;
            }
        }
    }
</style>

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章