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>

 

 

 

 

 

 

 

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