vue3使用echarts绘制地图

  1. 安装echarts
npm install echarts
  1. 下载地图的json数据【我这里是把json数据单独粘出来然后新建了一个文件china.json】
    下载中国及各个省份的地图数据
  2. 引入
import chinaJson from './china.json'
  1. 绘制地图
<template>
    <div ref="myChart" style="width: 1000px; height: 1000px;"></div>
</template>
<script setup>
import * as echarts from 'echarts'
import chinaJson from './china.json'
import { ref, onMounted } from 'vue'
const myChart = ref(null)

onMounted(() => {
    const myECharts = echarts.init(myChart.value);
    echarts.registerMap('china', chinaJson);
    
    var option;
    function randomData() {
        return Math.round(Math.random() * 1000);
    }

    var data = [{
        name: '北京',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '天津',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '上海',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '重庆',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '河北',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '河南',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '云南',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '辽宁',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '黑龙江',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '湖南',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '安徽',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '山东',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '新疆',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '江苏',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '浙江',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '江西',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '湖北',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '广西',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '甘肃',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '山西',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '内蒙古',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '陕西',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '吉林',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '福建',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '贵州',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '广东',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '青海',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '西藏',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '四川',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '宁夏',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '海南',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '台湾',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '香港',
        value1: randomData(),
        value2: randomData(),
    }, {
        name: '澳门',
        value1: randomData(),
        value2: randomData(),
    }];

    var resultdata0 = [];
    var resultdata1 = [];
    var resultdata2 = [];
    var sum0 = 0;
    var sum1 = 0;
    var sum2 = 0;
    var titledata = [];
    for (var i = 0; i < data.length; i++) {
        var d0 = {
            name: data[i].name,
            value: data[i].value1 + data[i].value2
        };
        var d1 = {
            name: data[i].name,
            value: data[i].value1
        };
        var d2 = {
            name: data[i].name,
            value: data[i].value2
        };
        titledata.push(data[i].name)
        resultdata0.push(d0);
        resultdata1.push(d1);
        resultdata2.push(d2);
        sum0 += data[i].value1 + data[i].value2;
        sum1 += data[i].value1;
        sum2 += data[i].value2;
    }

    function NumDescSort(a, b) {
        return a.value - b.value;
    }

    resultdata0.sort(NumDescSort);
    resultdata1.sort(NumDescSort);
    resultdata2.sort(NumDescSort);

    option = {
        title: [{
            text: '销售量统计',
            subtext: '纯属虚构',
            left: 'center'
        }, {
            text: '全部: ' + sum0,
            right: 120,
            top: 40,
            width: 100,
            textStyle: {
                color: '#fff',
                fontSize: 16
            }
        }, {
            text: "门板: " + sum1,
            right: 120,
            top: 40,
            width: 100,
            textStyle: {
                color: '#fff',
                fontSize: 16
            }
        }, {
            text: "拼框门: " + sum2,
            right: 120,
            top: 40,
            width: 100,
            textStyle: {
                color: '#fff',
                fontSize: 16
            }
        },],
        tooltip: {
            trigger: 'item'
        },
        legend: {
            orient: 'vertical',
            left: 'left',
            data: ['全部', '门板', '拼框门'],
            selectedMode: 'single',
        },
        visualMap: {
            min: 0,
            max: 2500,
            left: 'left',
            top: 'bottom',
            text: ['高', '低'],
            calculable: true,
            colorLightness: [0.2, 100],
            color: ['#c05050', '#e5cf0d', '#5ab1ef'],
            dimension: 0
        },
        toolbox: {
            show: true,
            orient: 'vertical',
            left: 'right',
            top: 'center',
            feature: {
                dataView: {
                    readOnly: false
                },
                restore: {},
                saveAsImage: {}
            }
        },
        grid: {
            right: 40,
            top: 100,
            bottom: 40,
            width: '30%'
        },
        xAxis: [{
            position: 'top',
            type: 'value',
            boundaryGap: false,
            splitLine: {
                show: false
            },
            axisLine: {
                show: false
            },
            axisTick: {
                show: false
            },
        }],
        yAxis: [{
            type: 'category',
            data: titledata,
            axisTick: {
                alignWithLabel: true
            }
        }],
        series: [{
            z: 1,
            name: '全部',
            type: 'map',
            map: 'china',
            left: '10',
            right: '35%',
            top: 100,
            bottom: "35%",
            zoom: 0.75,
            label: {
                normal: {
                    show: true
                },
                emphasis: {
                    show: true
                }
            },
            //roam: true,
            data: resultdata0
        }, {
            z: 1,
            name: '门板',
            type: 'map',
            map: 'china',
            left: '10',
            right: '35%',
            top: 100,
            bottom: "35%",
            zoom: 0.75,
            label: {
                normal: {
                    show: true
                },
                emphasis: {
                    show: true
                }
            },
            //roam: true,
            data: resultdata1
        }, {
            z: 1,
            name: '拼框门',
            type: 'map',
            map: 'china',
            left: '10',
            right: '35%',
            top: 100,
            bottom: "35%",
            zoom: 0.85,
            label: {
                normal: {
                    show: true
                },
                emphasis: {
                    show: true
                }
            },
            //roam: true,
            data: resultdata2
        }, {
            name: '全部',
            z: 2,
            type: 'bar',
            label: {
                normal: {
                    show: true
                },
                emphasis: {
                    show: true,
                }
            },
            itemStyle: {
                emphasis: {
                    color: "rgb(254,153,78)"
                }
            },
            data: resultdata0
        }, {
            name: '门板',
            z: 2,
            type: 'bar',
            label: {
                normal: {
                    show: true
                },
                emphasis: {
                    show: true
                }
            },
            itemStyle: {
                emphasis: {
                    color: "rgb(254,153,78)"
                }
            },
            data: resultdata1
        }, {
            name: '拼框门',
            z: 2,
            type: 'bar',
            label: {
                normal: {
                    show: true
                },
                emphasis: {
                    show: true
                }
            },
            itemStyle: {
                emphasis: {
                    color: "rgb(254,153,78)"
                }
            },
            data: resultdata2
        }, {
            name: '全部',
            z: 2,
            type: 'pie',
            radius: ['17%', '25%'],
            center: ['30%', '82.5%'],
            label: {
                normal: {
                    show: true
                },
                emphasis: {
                    show: true,
                }
            },
            itemStyle: {
                emphasis: {
                    color: "rgb(254,153,78)"
                }
            },
            data: resultdata0
        }, {
            name: '门板',
            z: 2,
            type: 'pie',
            radius: ['17%', '25%'],
            center: ['30%', '82.5%'],
            label: {
                normal: {
                    show: true
                },
                emphasis: {
                    show: true
                }
            },
            itemStyle: {
                emphasis: {
                    color: "rgb(254,153,78)"
                }
            },
            data: resultdata1
        }, {
            name: '拼框门',
            z: 2,
            type: 'pie',
            radius: ['17%', '25%'],
            center: ['30%', '82.5%'],
            label: {
                normal: {
                    show: true
                },
                emphasis: {
                    show: true
                }
            },
            itemStyle: {
                emphasis: {
                    color: "rgb(254,153,78)"
                }
            },
            data: resultdata2
        }]
    };

    option && myECharts.setOption(option)
})

</script>
<style></style>


<!-- <template >
    <div :id="id" :style="{ width: width, height: height }">

    </div>
</template>
<script setup>
import * as echarts from 'echarts'
import { onMounted, watch} from 'vue'
const props = defineProps({
    id: {
        type: String,
        default: 'myChart'
    },
    width: {
        type: String,
        default: '100%'
    },
    height: {
        type: String,
        default: '100%'
    },
    option: {
        type: Object,
        default: () => { }
    }
})
let myChart = null;
watch(props.option, () => {
    drawEcharts();
})
onMounted(() => {
    drawEcharts();
});
function drawEcharts() {
    myChart = echarts.init(document.getElementById(props.id));
    let option = props.option;
    option && myChart.setOption(option);

}

</script>
<style></style> -->

实现效果如下图:【上述代码使用的是可视化社区里的这个案例,如有需要自行按需更改即可!】
在这里插入图片描述
5. 封装echarts【具体封装流程可参考博客】

<template >
    <div :id="id" :style="{ width: width, height: height }">

    </div>
</template>
<script setup>
import * as echarts from 'echarts'
import { onMounted, watch } from 'vue'
import chinaJson from './china.json'
const props = defineProps({
    id: {
        type: String,
        default: 'myChart'
    },
    width: {
        type: String,
        default: '100%'
    },
    height: {
        type: String,
        default: '100%'
    },
    option: {
        type: Object,
        default: () => { }
    }
})
let myChart = null;
watch(props.option, () => {
    drawEcharts();
})
onMounted(() => {
    drawEcharts();
});
function drawEcharts() {
    myChart = echarts.init(document.getElementById(props.id));
    echarts.registerMap('china', chinaJson);
    let option = props.option;
    option && myChart.setOption(option);

}

</script>
<style></style>
  1. 直接在父组件中使用
<script setup>
import Echarts from './components/Echarts.vue';
import { ref, onMounted } from 'vue';
function randomData() {
  return Math.round(Math.random() * 1000);
}

var data = [{
  name: '北京',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '天津',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '上海',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '重庆',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '河北',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '河南',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '云南',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '辽宁',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '黑龙江',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '湖南',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '安徽',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '山东',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '新疆',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '江苏',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '浙江',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '江西',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '湖北',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '广西',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '甘肃',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '山西',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '内蒙古',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '陕西',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '吉林',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '福建',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '贵州',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '广东',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '青海',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '西藏',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '四川',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '宁夏',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '海南',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '台湾',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '香港',
  value1: randomData(),
  value2: randomData(),
}, {
  name: '澳门',
  value1: randomData(),
  value2: randomData(),
}];

var resultdata0 = [];
var resultdata1 = [];
var resultdata2 = [];
var sum0 = 0;
var sum1 = 0;
var sum2 = 0;
var titledata = [];
for (var i = 0; i < data.length; i++) {
  var d0 = {
    name: data[i].name,
    value: data[i].value1 + data[i].value2
  };
  var d1 = {
    name: data[i].name,
    value: data[i].value1
  };
  var d2 = {
    name: data[i].name,
    value: data[i].value2
  };
  titledata.push(data[i].name)
  resultdata0.push(d0);
  resultdata1.push(d1);
  resultdata2.push(d2);
  sum0 += data[i].value1 + data[i].value2;
  sum1 += data[i].value1;
  sum2 += data[i].value2;
}

function NumDescSort(a, b) {
  return a.value - b.value;
}

resultdata0.sort(NumDescSort);
resultdata1.sort(NumDescSort);
resultdata2.sort(NumDescSort);

const lineOption = ref({});
lineOption.value = {
  title: [{
    text: '销售量统计',
    subtext: '纯属虚构',
    left: 'center'
  }, {
    text: '全部: ' + sum0,
    right: 120,
    top: 40,
    width: 100,
    textStyle: {
      color: '#fff',
      fontSize: 16
    }
  }, {
    text: "门板: " + sum1,
    right: 120,
    top: 40,
    width: 100,
    textStyle: {
      color: '#fff',
      fontSize: 16
    }
  }, {
    text: "拼框门: " + sum2,
    right: 120,
    top: 40,
    width: 100,
    textStyle: {
      color: '#fff',
      fontSize: 16
    }
  },],
  tooltip: {
    trigger: 'item'
  },
  legend: {
    orient: 'vertical',
    left: 'left',
    data: ['全部', '门板', '拼框门'],
    selectedMode: 'single',
  },
  visualMap: {
    min: 0,
    max: 2500,
    left: 'left',
    top: 'bottom',
    text: ['高', '低'],
    calculable: true,
    colorLightness: [0.2, 100],
    color: ['#c05050', '#e5cf0d', '#5ab1ef'],
    dimension: 0
  },
  toolbox: {
    show: true,
    orient: 'vertical',
    left: 'right',
    top: 'center',
    feature: {
      dataView: {
        readOnly: false
      },
      restore: {},
      saveAsImage: {}
    }
  },
  grid: {
    right: 40,
    top: 100,
    bottom: 40,
    width: '30%'
  },
  xAxis: [{
    position: 'top',
    type: 'value',
    boundaryGap: false,
    splitLine: {
      show: false
    },
    axisLine: {
      show: false
    },
    axisTick: {
      show: false
    },
  }],
  yAxis: [{
    type: 'category',
    data: titledata,
    axisTick: {
      alignWithLabel: true
    }
  }],
  series: [{
    z: 1,
    name: '全部',
    type: 'map',
    map: 'china',
    left: '10',
    right: '35%',
    top: 100,
    bottom: "35%",
    zoom: 0.75,
    label: {
      normal: {
        show: true
      },
      emphasis: {
        show: true
      }
    },
    //roam: true,
    data: resultdata0
  }, {
    z: 1,
    name: '门板',
    type: 'map',
    map: 'china',
    left: '10',
    right: '35%',
    top: 100,
    bottom: "35%",
    zoom: 0.75,
    label: {
      normal: {
        show: true
      },
      emphasis: {
        show: true
      }
    },
    //roam: true,
    data: resultdata1
  }, {
    z: 1,
    name: '拼框门',
    type: 'map',
    map: 'china',
    left: '10',
    right: '35%',
    top: 100,
    bottom: "35%",
    zoom: 0.85,
    label: {
      normal: {
        show: true
      },
      emphasis: {
        show: true
      }
    },
    //roam: true,
    data: resultdata2
  }, {
    name: '全部',
    z: 2,
    type: 'bar',
    label: {
      normal: {
        show: true
      },
      emphasis: {
        show: true,
      }
    },
    itemStyle: {
      emphasis: {
        color: "rgb(254,153,78)"
      }
    },
    data: resultdata0
  }, {
    name: '门板',
    z: 2,
    type: 'bar',
    label: {
      normal: {
        show: true
      },
      emphasis: {
        show: true
      }
    },
    itemStyle: {
      emphasis: {
        color: "rgb(254,153,78)"
      }
    },
    data: resultdata1
  }, {
    name: '拼框门',
    z: 2,
    type: 'bar',
    label: {
      normal: {
        show: true
      },
      emphasis: {
        show: true
      }
    },
    itemStyle: {
      emphasis: {
        color: "rgb(254,153,78)"
      }
    },
    data: resultdata2
  }, {
    name: '全部',
    z: 2,
    type: 'pie',
    radius: ['17%', '25%'],
    center: ['30%', '82.5%'],
    label: {
      normal: {
        show: true
      },
      emphasis: {
        show: true,
      }
    },
    itemStyle: {
      emphasis: {
        color: "rgb(254,153,78)"
      }
    },
    data: resultdata0
  }, {
    name: '门板',
    z: 2,
    type: 'pie',
    radius: ['17%', '25%'],
    center: ['30%', '82.5%'],
    label: {
      normal: {
        show: true
      },
      emphasis: {
        show: true
      }
    },
    itemStyle: {
      emphasis: {
        color: "rgb(254,153,78)"
      }
    },
    data: resultdata1
  }, {
    name: '拼框门',
    z: 2,
    type: 'pie',
    radius: ['17%', '25%'],
    center: ['30%', '82.5%'],
    label: {
      normal: {
        show: true
      },
      emphasis: {
        show: true
      }
    },
    itemStyle: {
      emphasis: {
        color: "rgb(254,153,78)"
      }
    },
    data: resultdata2
  }]
};
</script>

<template>
 <Echarts :width="'90vw'" :height="'90vh'" :option="lineOption" id="line" />
</template>

实现效果同上

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐