啊,这是一个美好的一天,这一天我也不知道我要干啥。
最终结果
<template>
<div id="chart" style="width: 100%; height: 100%"></div>
</template>
<script>
import * as echarts from "echarts";
import "./china";
import resize from "@/utils/mixins/resize";
export default {
name: "chinaEchart",
mixins: [resize],
props: {
data: {
type: Array,
default: () => [],
},
},
data() {
return {
chart: null,
dataList: [],
chinaJson: [], //引入的地图数据
};
},
watch: {
data(val) {
this.setOptions(val);
},
},
mounted() {
this.chinaJson = echarts.getMap("china")?.geoJSON?.features;
console.log(this.chinaJson);
this.dataList = [
// { name: "南海诸岛", value: 0 },
{ name: "北京", value: this.randomValue() },
{ name: "天津", value: this.randomValue() },
{ name: "上海", value: this.randomValue() },
{ name: "重庆", value: this.randomValue() },
{ name: "河北", value: this.randomValue() },
{ name: "河南", value: this.randomValue() },
{ name: "云南", value: this.randomValue() },
{ name: "辽宁", value: this.randomValue() },
{ name: "黑龙江", value: this.randomValue() },
{ name: "湖南", value: this.randomValue() },
{ name: "安徽", value: this.randomValue() },
{ name: "山东", value: this.randomValue() },
{ name: "新疆", value: this.randomValue() },
{ name: "江苏", value: this.randomValue() },
{ name: "浙江", value: this.randomValue() },
{ name: "江西", value: this.randomValue() },
{ name: "湖北", value: this.randomValue() },
{ name: "广西", value: this.randomValue() },
{ name: "甘肃", value: this.randomValue() },
{ name: "山西", value: this.randomValue() },
{ name: "内蒙古", value: this.randomValue() },
{ name: "陕西", value: this.randomValue() },
{ name: "吉林", value: this.randomValue() },
{ name: "福建", value: this.randomValue() },
{ name: "贵州", value: this.randomValue() },
{ name: "广东", value: this.randomValue() },
{ name: "青海", value: this.randomValue() },
{ name: "西藏", value: this.randomValue() },
{ name: "四川", value: this.randomValue() },
{ name: "宁夏", value: this.randomValue() },
{ name: "海南", value: this.randomValue() },
{ name: "台湾", value: this.randomValue() },
{ name: "香港", value: this.randomValue() },
{ name: "澳门", value: this.randomValue() },
];
this.$nextTick((_) => {
this.initChart();
this.renderEachArea();
});
},
beforeDestroy() {
if (!this.chart) {
return;
}
this.chart.dispose();
this.chart = null;
},
methods: {
randomValue() {
return Math.round(Math.random() * 1000);
},
initChart() {
this.chart = echarts.init(this.$el);
this.setOptions(this.data);
},
setOptions(data = []) {
let option = {
// tooltip: {
// formatter: function (params, ticket, callback) {
// if (!params.value) {
// params.value = "-";
// }
// return (
// params.seriesName + "<br />" + params.name + ":" + params.value
// );
// }, //数据格式化
// },
// visualMap: {
// min: 0,
// max: 1500,
// left: "left",
// top: "bottom",
// text: ["高", "低"], //取值范围的文字
// inRange: {
// color: ["#e0ffff", "#006edd"], //取值范围的颜色
// },
// show: true, //图注
// },
// 地图背景颜色
backgroundColor: new echarts.graphic.RadialGradient(0.5, 0.5, 0.4, [
{
offset: 0,
color: "#4b5769",
},
{
offset: 1,
color: "#404a59",
},
]),
geo: {
map: "china",
roam: false, //不开启缩放和平移
zoom: 1.23, //视角缩放比例
label: {
normal: {
show: false,
fontSize: "10",
color: "rgba(0,0,0,0.7)",
},
},
itemStyle: {
normal: {
borderColor: "rgba(0, 0, 0, 0.2)",
areaColor: "#55C3FC", //地图块颜色
},
emphasis: {
areaColor: "#ff4536", //鼠标选择区域颜色
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: "rgba(0, 0, 0, 0.5)",
},
},
emphasis: {
disabled: true,
focus: "self",
},
// 在地图中对特定的区域配置样式。
regions: [
{
name: "北京",
itemStyle: {
areaColor: "red",
color: "red",
},
},
{
name: "江苏",
itemStyle: {
areaColor: "skyblue",
},
},
],
},
series: [
{
name: "信息量",
type: "map",
geoIndex: 0,
data: this.dataList,
},
],
};
this.chart.setOption(option);
this.chart.on("click", (param) => {
console.log(param);
alert(param.name);
// this.$router.push("/home/importData");
});
},
renderEachArea() {
// 测试echartsInstance. convertToPixel方法
// https://echarts.apache.org/zh/api.html#echartsInstance.convertToPixel
// let a = this.chart.convertToPixel("geo", [128.3324, 89.5344]);
// console.log(a);
const areaOption = {
xAxis: [],
yAxis: [],
grid: [],
series: [],
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
color: ["#ff4565", "#56844f"],
};
this.dataList.forEach((item, idx) => {
let city = this.chinaJson.find(
(val) => val?.properties?.name == item.name
);
// console.log(city);
// 依据城市地图坐标(经纬度)获取在echart图上的偏移量(定位)
let EcPxy = this.chart.convertToPixel(
"geo",
city?.properties?.cp || []
);
// console.log(EcPxy);
//基础echart同时绘制多个数据配置
areaOption.xAxis.push({
id: idx, // 组件id,在配置中引用标识
gridIndex: idx, // x轴所在的grid的索引
type: "category", // 坐标轴类型
name: item.name, // 坐标轴名称
nameLocation: "middle",
data: [item.name],
nameGap: 3, // 坐标轴名称与轴线之间的距离
splitLine: {
// 坐标轴在 grid 区域中的分隔线
show: false,
},
axisTick: {
// 坐标轴刻度
show: false,
},
axisLabel: {
// 坐标轴刻度标签
show: false,
},
axisLine: {
// 坐标轴轴线
onZero: false,
lineStyle: {
color: "#666",
},
},
z: 100,
});
areaOption.yAxis.push({
id: idx, // 组件id,在配置中引用标识
gridIndex: idx, // x轴所在的grid的索引
splitLine: {
// 坐标轴在 grid 区域中的分隔线
show: false,
},
axisTick: {
// 坐标轴刻度
show: false,
},
axisLabel: {
// 坐标轴刻度标签
show: false,
},
axisLine: {
// 坐标轴轴线
show: false,
lineStyle: {
color: "#1C70B6",
},
},
z: 100,
});
areaOption.grid.push({
id: idx, // 组件id,在配置中引用标识
width: 30, // 组件的宽度
height: 40, // 组件的高度
left: EcPxy[0] - 15, // 离容器左侧的距离
top: EcPxy[1] - 40, // 离容器上侧的距离
z: 100,
});
areaOption.series.push(
{
name: "一号",
type: "bar", // 柱状图
xAxisId: idx, // 使用的x轴的id
yAxisId: idx, // 使用的y轴的id
barGap: 0, // 柱间距离
barCategoryGap: 0, // 同一系列的柱间距离
data: [item.value], // 柱子数据
z: 100,
},
{
name: "二号",
type: "bar", // 柱状图
xAxisId: idx, // 使用的x轴的id
yAxisId: idx, // 使用的y轴的id
barGap: 0, // 柱间距离
barCategoryGap: 0, // 同一系列的柱间距离
data: [50], // 柱子数据
z: 100,
}
);
});
console.log(areaOption);
// 应用配置
this.chart.setOption(areaOption);
},
},
};
</script>
我的解决问题流程
- 会使用搜索引擎
- 使用过echart
- 知道echart的文档在哪里
- 掘金是世界上最棒的网站!
知道要做的项目要用
- vue项目
- 本人原来绘制地图使用的是高德地图api,但是组长告诉我原来差不多的项目使用的是echart。
查看echart实例
- 去echart官方的实例中去找地图,最后找到了一个美国的地图绘制的东西。
- 细看,拷贝下来。发现运行不了。那我细看个勾八。
百度关键字搜索
- 搜索内容:echart地图绘制
- 当然会找到了,但是他没贴图,我还是不确定。所以老子不去试。
掘金永远的神
- 搜索内容:echart地图上铺设柱状图
- 点开看到图了!但是不是关联的,一个是北京地图并上面存在柱状图的一个是绘制中国地图的
- 本人看了一下,决定可以用!果然掘金是我的神!
开始测试
vue项目使用echart,echart封装成组件
<template>
<div id="chart" style="width: 100%; height: 100%"></div>
</template>
<script>
// "echarts": "^5.3.2"
import * as echarts from "echarts";
// vue-admin项目中抓取的大小可以变化
import resize from "@/utils/mixins/resize";
export default {
name: "chinaEchart",
mixins: [resize],
props: {
data: {
type: Array,
default: () => [],
},
},
data() {
return {
chart: null,
dataList: []
};
},
watch: {
data(val) {
this.setOptions(val);
},
},
mounted() {
this.$nextTick((_) => {
this.initChart();
});
},
beforeDestroy() {
if (!this.chart) {
return;
}
this.chart.dispose();
this.chart = null;
},
methods: {
randomValue() {
return Math.round(Math.random() * 1000);
},
initChart() {
this.chart = echarts.init(this.$el);
this.setOptions(this.data);
},
setOptions(data = []) {
let option = {
//...数据内容
};
this.chart.setOption(option);
},
},
};
</script>
绘制中国地图的样式
代码没测试,但应该可以:
<template>
<div id="chart" style="width: 100%; height: 100%"></div>
</template>
<script>
// "echarts": "^5.3.2"
import * as echarts from "echarts";
// node_modules/echart/js下拉出来
import "./china";
// vue-admin项目中抓取的
import resize from "@/utils/mixins/resize";
export default {
name: "chinaEchart",
mixins: [resize],
props: {
data: {
type: Array,
default: () => [],
},
},
data() {
return {
chart: null,
dataList: [],
};
},
watch: {
data(val) {
this.setOptions(val);
},
},
mounted() {
this.dataList = [
// { name: "南海诸岛", value: 0 },
{ name: "北京", value: this.randomValue() },
{ name: "天津", value: this.randomValue() },
{ name: "上海", value: this.randomValue() },
{ name: "重庆", value: this.randomValue() },
{ name: "河北", value: this.randomValue() },
{ name: "河南", value: this.randomValue() },
{ name: "云南", value: this.randomValue() },
{ name: "辽宁", value: this.randomValue() },
{ name: "黑龙江", value: this.randomValue() },
{ name: "湖南", value: this.randomValue() },
{ name: "安徽", value: this.randomValue() },
{ name: "山东", value: this.randomValue() },
{ name: "新疆", value: this.randomValue() },
{ name: "江苏", value: this.randomValue() },
{ name: "浙江", value: this.randomValue() },
{ name: "江西", value: this.randomValue() },
{ name: "湖北", value: this.randomValue() },
{ name: "广西", value: this.randomValue() },
{ name: "甘肃", value: this.randomValue() },
{ name: "山西", value: this.randomValue() },
{ name: "内蒙古", value: this.randomValue() },
{ name: "陕西", value: this.randomValue() },
{ name: "吉林", value: this.randomValue() },
{ name: "福建", value: this.randomValue() },
{ name: "贵州", value: this.randomValue() },
{ name: "广东", value: this.randomValue() },
{ name: "青海", value: this.randomValue() },
{ name: "西藏", value: this.randomValue() },
{ name: "四川", value: this.randomValue() },
{ name: "宁夏", value: this.randomValue() },
{ name: "海南", value: this.randomValue() },
{ name: "台湾", value: this.randomValue() },
{ name: "香港", value: this.randomValue() },
{ name: "澳门", value: this.randomValue() },
];
this.$nextTick((_) => {
this.initChart();
});
},
beforeDestroy() {
if (!this.chart) {
return;
}
this.chart.dispose();
this.chart = null;
},
methods: {
randomValue() {
return Math.round(Math.random() * 1000);
},
initChart() {
this.chart = echarts.init(this.$el);
this.setOptions(this.data);
},
setOptions(data = []) {
let option = {
tooltip: {
formatter: function (params, ticket, callback) {
if (!params.value) {
params.value = "-";
}
return (
params.seriesName + "<br />" + params.name + ":" + params.value
);
}, //数据格式化
},
visualMap: {
min: 0,
max: 1500,
left: "left",
top: "bottom",
text: ["高", "低"], //取值范围的文字
inRange: {
color: ["#e0ffff", "#006edd"], //取值范围的颜色
},
show: true, //图注
},
geo: {
map: "china",
roam: false, //不开启缩放和平移
zoom: 1.23, //视角缩放比例
label: {
normal: {
show: false,
fontSize: "10",
color: "rgba(0,0,0,0.7)",
},
},
itemStyle: {
normal: {
borderColor: "rgba(0, 0, 0, 0.2)",
areaColor: "#55C3FC", //地图块颜色
},
emphasis: {
areaColor: "#ff4536", //鼠标选择区域颜色
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: "rgba(0, 0, 0, 0.5)",
},
},
},
series: [
{
name: "信息量",
type: "map",
geoIndex: 0,
data: this.dataList,
},
],
};
this.chart.setOption(option);
this.chart.on("click", (param) => {
console.log(param);
alert(param.name);
// this.$router.push("/home/importData");
});
},
},
};
</script>
全部添加过去
代码最上面。修改了一些东西。
逻辑
绘制地图数据,在地图数据的对应像素点绘制柱状图。(我弄出来才知道的)
难点
- 地图绘制,可以找到案例。
- china.js在哪里获取,install后文件夹中自带
- 地图的有些配置字段只有
v5.3.0
才能用
- 知道获取对应的像素坐标可以在指定位置绘制折线图
- 使用城市的经纬度可以获取像素坐标
this.chart.convertToPixel("geo", [128.3324, 89.5344])
- 思考:是否可以直接循环多个柱状图,不使用现在的逻辑
- 问题:宽度100%的情况下,柱状图固定住了。
- 我去找我的神去了。
- 使用城市的经纬度可以获取像素坐标
<template>
<div id="chart" style="width: 100%; height: 100%"></div>
</template>
<script>
// "echarts": "^5.3.2",
import * as echarts from "echarts";
// node_modules/echart/js下拉出来
import "./china";
// vue-admin项目中抓取的
import resize from "@/utils/mixins/resize";
const _ = require("lodash");
export default {
name: "chinaEchart",
mixins: [resize],
props: {
data: {
type: Array,
default: () => [],
},
},
data() {
return {
chart: null,
dataList: [],
chinaJson: [], //引入的地图数据
};
},
watch: {
data(val) {
this.setOptions(val);
},
},
mounted() {
this.chinaJson = echarts.getMap("china")?.geoJSON?.features;
this.dataList = [
// { name: "南海诸岛", value: 0 },
{ name: "北京", value: this.randomValue() },
{ name: "天津", value: this.randomValue() },
{ name: "上海", value: this.randomValue() },
{ name: "重庆", value: this.randomValue() },
{ name: "河北", value: this.randomValue() },
{ name: "河南", value: this.randomValue() },
{ name: "云南", value: this.randomValue() },
{ name: "辽宁", value: this.randomValue() },
{ name: "黑龙江", value: this.randomValue() },
{ name: "湖南", value: this.randomValue() },
{ name: "安徽", value: this.randomValue() },
{ name: "山东", value: this.randomValue() },
{ name: "新疆", value: this.randomValue() },
{ name: "江苏", value: this.randomValue() },
{ name: "浙江", value: this.randomValue() },
{ name: "江西", value: this.randomValue() },
{ name: "湖北", value: this.randomValue() },
{ name: "广西", value: this.randomValue() },
{ name: "甘肃", value: this.randomValue() },
{ name: "山西", value: this.randomValue() },
{ name: "内蒙古", value: this.randomValue() },
{ name: "陕西", value: this.randomValue() },
{ name: "吉林", value: this.randomValue() },
{ name: "福建", value: this.randomValue() },
{ name: "贵州", value: this.randomValue() },
{ name: "广东", value: this.randomValue() },
{ name: "青海", value: this.randomValue() },
{ name: "西藏", value: this.randomValue() },
{ name: "四川", value: this.randomValue() },
{ name: "宁夏", value: this.randomValue() },
{ name: "海南", value: this.randomValue() },
{ name: "台湾", value: this.randomValue() },
{ name: "香港", value: this.randomValue() },
{ name: "澳门", value: this.randomValue() },
];
this.$nextTick(() => {
this.initChart();
this.renderEachArea();
// 窗口变化监听,不用防抖的话有问题
window.addEventListener(
"resize",
_.debounce(() => {
this.renderEachArea();
}, 300)
);
});
},
beforeDestroy() {
if (!this.chart) {
return;
}
this.chart.dispose();
this.chart = null;
},
methods: {
randomValue() {
return Math.round(Math.random() * 1000);
},
initChart() {
this.chart = echarts.init(this.$el);
this.setOptions(this.data);
},
setOptions(data = []) {
let option = {
// tooltip: {
// formatter: function (params, ticket, callback) {
// if (!params.value) {
// params.value = "-";
// }
// return (
// params.seriesName + "<br />" + params.name + ":" + params.value
// );
// }, //数据格式化
// },
// visualMap: {
// min: 0,
// max: 1500,
// left: "left",
// top: "bottom",
// text: ["高", "低"], //取值范围的文字
// inRange: {
// color: ["#e0ffff", "#006edd"], //取值范围的颜色
// },
// show: true, //图注
// },
// 地图背景颜色
// backgroundColor: new echarts.graphic.RadialGradient(0.5, 0.5, 0.4, [
// {
// offset: 0,
// color: "#4b5769",
// },
// {
// offset: 1,
// color: "#404a59",
// },
// ]),
geo: {
map: "china",
roam: false, //不开启缩放和平移
zoom: 1.23, //视角缩放比例
label: {
normal: {
show: false,
fontSize: "10",
color: "rgba(0,0,0,0.7)",
},
},
itemStyle: {
normal: {
borderColor: "rgba(0, 0, 0, 0.2)",
areaColor: "#55C3FC", //地图块颜色
},
emphasis: {
areaColor: "#ff4536", //鼠标选择区域颜色
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: "rgba(0, 0, 0, 0.5)",
},
},
emphasis: {
disabled: true,
focus: "self",
},
// 在地图中对特定的区域配置样式。
regions: [
{
name: "北京",
itemStyle: {
areaColor: "red",
color: "red",
},
},
{
name: "江苏",
itemStyle: {
areaColor: "#ff6655",
},
},
],
},
series: [
{
name: "信息量",
type: "map",
geoIndex: 0,
data: this.dataList,
},
],
};
this.chart.setOption(option);
this.chart.on("click", (param) => {
console.log(param);
});
// 监听地图的拖拽与移动
// 防抖!
this.chart.on(
"geoRoam",
_.debounce((param) => {
this.renderEachArea();
}),
300
);
},
renderEachArea() {
// 测试echartsInstance. convertToPixel方法
// https://echarts.apache.org/zh/api.html#echartsInstance.convertToPixel
// let a = this.chart.convertToPixel("geo", [128.3324, 89.5344]);
// console.log(a);
const areaOption = {
xAxis: [],
yAxis: [],
grid: [],
series: [],
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
color: ["#ff4565", "#56844f"],
};
this.dataList.forEach((item, idx) => {
let city = this.chinaJson.find(
(val) => val?.properties?.name == item.name
);
// console.log(city);
// 依据城市地图坐标(经纬度)获取在echart图上的偏移量(定位)
let EcPxy = this.chart.convertToPixel(
"geo",
city?.properties?.cp || []
);
// console.log(EcPxy);
//基础echart同时绘制多个数据配置
areaOption.xAxis.push({
id: idx, // 组件id,在配置中引用标识
gridIndex: idx, // x轴所在的grid的索引
type: "category", // 坐标轴类型
name: item.name, // 坐标轴名称
nameLocation: "middle",
data: [item.name],
nameGap: 3, // 坐标轴名称与轴线之间的距离
splitLine: {
// 坐标轴在 grid 区域中的分隔线
show: false,
},
axisTick: {
// 坐标轴刻度
show: false,
},
axisLabel: {
// 坐标轴刻度标签
show: false,
},
axisLine: {
// 坐标轴轴线
onZero: false,
lineStyle: {
color: "#666",
},
},
z: 100,
});
areaOption.yAxis.push({
id: idx, // 组件id,在配置中引用标识
gridIndex: idx, // x轴所在的grid的索引
splitLine: {
// 坐标轴在 grid 区域中的分隔线
show: false,
},
axisTick: {
// 坐标轴刻度
show: false,
},
axisLabel: {
// 坐标轴刻度标签
show: false,
},
axisLine: {
// 坐标轴轴线
show: false,
lineStyle: {
color: "#1C70B6",
},
},
z: 100,
});
areaOption.grid.push({
id: idx, // 组件id,在配置中引用标识
width: 30, // 组件的宽度
height: 40, // 组件的高度
left: EcPxy[0] - 15, // 离容器左侧的距离
top: EcPxy[1] - 40, // 离容器上侧的距离
z: 100,
});
areaOption.series.push(
{
name: "一号",
type: "bar", // 柱状图
xAxisId: idx, // 使用的x轴的id
yAxisId: idx, // 使用的y轴的id
barGap: 0, // 柱间距离
barCategoryGap: 0, // 同一系列的柱间距离
data: [item.value], // 柱子数据
z: 100,
},
{
name: "二号",
type: "bar", // 柱状图
xAxisId: idx, // 使用的x轴的id
yAxisId: idx, // 使用的y轴的id
barGap: 0, // 柱间距离
barCategoryGap: 0, // 同一系列的柱间距离
data: [50], // 柱子数据
z: 100,
}
);
});
// console.log(areaOption);
// 应用配置
this.chart.setOption(areaOption);
},
},
};
</script>