Echarts之移动的点位(图标)图(任何图片)

介绍

  1. 本文以react来举例,其他的框架大差不差。
  2. 功能介绍:
    (1)给定一张图片,在这个图片上有小车或其他动态点位需要以固定线路移动。
    (2)echarts默认支持SVG图片格式JSON地图格式。本文会转译其他图片为svg(目前仅仅简单转译,如果有其他好的方法直接替换就行了),然后支持echarts调用。

实现

  1. @/components/ImgLine/index.ts组件代码
import { useEffect, useState } from 'react'
import * as echarts from 'echarts/core';
import {
  TooltipComponent,
  TooltipComponentOption,
  GeoComponent,
  GeoComponentOption
} from 'echarts/components';
import { LinesChart, LinesSeriesOption } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
import { svgFn, getBase64 } from './utils/index';

echarts.use([TooltipComponent, GeoComponent, LinesChart, CanvasRenderer]);

type EChartsOption = echarts.ComposeOption<
  TooltipComponentOption | GeoComponentOption | LinesSeriesOption
>;

let option: EChartsOption;

const ImgLine = () => {
  // 为了实现数据双向绑定的代码 - -;vue 直接更改值就完事。
  const [myChart, setMyChart] = useState<any>(null)
  const renderFn = () => {
    let chartDom = document.getElementById('main')!;
    let myChart = echarts.init(chartDom);
    getBase64('http://localhost:8081/images/public_bg.png').then((config: any) => {
      echarts.registerMap('ksia-ext-plan', { svg: svgFn(config) });
      option = {
        tooltip: {},
        geo: {
          map: 'ksia-ext-plan',
          roam: true,
          layoutCenter: ['50%', '50%'],
          layoutSize: '100%'
        },
        series: [
          {
            name: 'Route',
            type: 'lines',
            coordinateSystem: 'geo',
            geoIndex: 0,
            emphasis: {
              label: {
                show: false
              }
            },
            polyline: true,
            lineStyle: {
              color: '#c46e54',
              width: 0
            },
            effect: {
              show: true,
              period: 8,
              color: '#a10000',
              // constantSpeed: 80,
              trailLength: 0,
              symbolSize: [12, 30],
              symbol:
                'path://M87.1667 3.8333L80.5.5h-60l-6.6667 3.3333L.5 70.5v130l10 10h80l10 -10v-130zM15.5 190.5l15 -20h40l15 20zm75 -65l-15 5v35l15 15zm-80 0l15 5v35l-15 15zm65 0l15 -5v-40l-15 20zm-50 0l-15 -5v-40l15 20zm 65,-55 -15,25 c -15,-5 -35,-5 -50,0 l -15,-25 c 25,-15 55,-15 80,0 z'
            },
            z: 100,
            data: [
              {
                effect: {
                  color: '#fff',
                  constantSpeed: 100, // 多少像素每秒
                  delay: 0
                },
                coords: [
                  [50.875133928571415, 242.66287667410717],
                  [62.03696428571425, 264.482421875],
                  [72.63357421874997, 273.62779017857144],
                  [92.78291852678569, 285.869140625],
                  [113.43637834821425, 287.21854073660717],
                  [141.44788783482142, 288.92947823660717],
                  [191.71686104910714, 289.5507114955357],
                  [198.3060072544643, 294.0673828125],
                  [204.99699497767858, 304.60288783482144],
                  [210.79177734375003, 316.7373046875],
                  [212.45179408482142, 329.3656529017857],
                  [210.8885267857143, 443.3925083705358],
                  [215.35936941964286, 453.00634765625],
                  [224.38761997767858, 452.15087890625],
                  [265.71490792410714, 452.20179966517856],
                  [493.3408844866072, 453.77525111607144],
                  [572.8892940848216, 448.77992466517856],
                  [608.9513755580358, 448.43366350446433],
                  [619.99099609375, 450.8778599330358],
                  [624.2479715401787, 456.2194475446429],
                  [628.1434095982145, 463.9899553571429],
                  [629.8492550223216, 476.0276227678571],
                  [631.2750362723216, 535.7322126116071],
                  [624.6757059151787, 546.6496233258929],
                  [617.1801702008929, 552.6480887276786],
                  [603.7269056919645, 554.5066964285714],
                  [588.0178515625, 557.5517578125],
                  [529.4386104910716, 556.2991071428571],
                  [422.1994921875001, 551.38525390625],
                  [291.66921875, 552.5767996651786],
                  [219.4279380580357, 547.4949079241071],
                  [209.53912667410714, 541.5931919642858],
                  [206.70793247767858, 526.1947544642858],
                  [206.70793247767858, 507.4049944196429],
                  [206.12234375000003, 468.7663225446429],
                  [204.48778738839286, 459.44782366071433],
                  [197.56256417410714, 452.8943219866071],
                  [170.31995814732142, 456.27546037946433],
                  [1.8078906249999704, 460.5935407366071]
                ]
              },
              {
                effect: {
                  color: '#f60',
                  constantSpeed: 100,
                  delay: 0
                },
                coords: [
                  [1920.1, 287.98756],
                  [689.1, 291.0477],
                  [301.16, 290.49717],
                  [229.12, 291.73856],
                  [220.13, 297.4043],
                  [214.13, 308.52144],
                  [213.13, 421.35],
                  [213.18, 443.0571],
                  [222.16, 455.95433],
                  [271.15, 454.37856],
                  [359.16, 455.9358],
                  [580.1, 448.11233],
                  [627.1, 460.7469],
                  [632.1, 536.6388],
                  [628.1, 548.4776],
                  [612.1, 556.8234],
                  [543.1, 555.4743],
                  [429.1, 551.9404],
                  [293.16, 551.2158],
                  [226.15, 556.0686],
                  [215.14, 562.7229],
                  [213.14, 591.6058],
                  [212.16, 625.6729],
                  [197.16, 645.0786],
                  [187.16, 647.0871],
                  [101.16, 649.029],
                  [69.91, 650.161],
                  [56.41, 656.826],
                  [51.11, 1080.254]
                ]
              },
              {
                effect: {
                  color: '#ff0',
                  constantSpeed: 60,
                  delay: 0
                },
                coords: [
                  [2.5920703124999704, 450.66908482142856],
                  [204.0651450892857, 453.13364955357144],
                  [378.72844029017864, 453.13874162946433],
                  [551.1817745535716, 456.1532505580358],
                  [578.3734598214287, 456.91196986607144],
                  [601.2317885044645, 458.9895368303571],
                  [614.1503850446429, 462.1669921875],
                  [618.99294921875, 479.68882533482144],
                  [620.0826534598216, 513.5969587053571],
                  [615.6932840401787, 528.7306082589286],
                  [608.4829045758929, 533.2625558035714],
                  [592.7127455357145, 534.9582170758929],
                  [583.09890625, 527.5492466517858],
                  [578.6535239955358, 516.4077845982143],
                  [578.6535239955358, 498.36146763392856],
                  [577.9966462053571, 477.0613141741071],
                  [575.3691350446429, 469.1940569196429],
                  [569.0753292410716, 462.63037109375],
                  [553.9518638392858, 460.6444614955358],
                  [298.10051060267864, 465.61432756696433],
                  [193.49908761160714, 460.1759905133929],
                  [116.40505859374997, 465.78236607142856],
                  [3.5137360491071092, 463.47565569196433]
                ]
              }
            ]
          }
        ]
      };
      myChart.setOption(option);
      setMyChart(myChart)
    })
  }
  // dom节点渲染完毕后渲染一次(vue: mounted 生命周期)
  useEffect(() => {
    renderFn();
    // option && myChart?.setOption(option);
  }, [])
  return <div>
    <div id='main' style={{ width: '500px', height: '500px' }}></div>
  </div>
}
export default ImgLine
  1. @/components/ImgLine/utils/index.ts
// 简易生成svg图片代码
export const svgFn = ({ src, width, height }: any) => `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="${width}px" height="${height}px" viewBox="0 0 ${width} ${height}" enable-background="new 0 0 ${width} ${height}" xml:space="preserve">  <image id="image0" width="${width}" height="${height}" x="0" y="0"
    href="${src}" />
</svg>
`
// 给入图片地址生成base64
export const getBase64: any = (imgUrl: any) => new Promise((resolve) => {
    // http原生get请求操作如下- -!
    const xhr: any = new XMLHttpRequest();
    xhr.open("get", imgUrl, true);
    // 返回内容为blob格式。
    xhr.responseType = "blob";
    xhr.onload = function () {
      if (this.status !== 200) return;
      //得到一个blob对象
      const blob: any = this.response;
      console.log("blob", blob)
      // 异步读取文件机制。
      const fileReader = new FileReader();
      fileReader.onloadend = function (e: any) {
        const base64 = e.target.result;
        console.log("base64:", base64)
        // 为了获取图片的宽高;
        const img = new Image();
        img.src = base64;
        img.onload = () => resolve({ src: base64, width: img.width, height: img.height })
      };
      // 会读取指定的 Blob 或 File 对象。并生成data URl(base64编码)
      fileReader.readAsDataURL(blob);
    }
    xhr.send();
  })

使用

  1. 调用代码
import styles from './index.less';
import ImgLine from '@/components/ImgLine';

const HomePage = () => {
  return (
      <div className={styles.container}>
        <div style={{ width: '1000px', height: '400px' }}>
            <ImgLine />
          </div >
      </div>
  );
};

export default HomePage;

  1. 效果介绍
    (1)路线本文是使用的1080 x 1920 路线(像素)
    在这里插入图片描述

在这里插入图片描述

参考资料

  1. echarts示例
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值