leaflet学习笔记-带过滤的图例(九)

前言

图例不只能够帮助我们在查看地图的时候更加方便容易地分辨不同颜色代表的要素,本文要介绍的图例组件还可以按需求过滤掉不用显示的要素,使地图的更能清晰的显示我们需要显示的内容

技术核心

说到过滤要素,第一时间想到的就是滑块组件,这里我们选择了Element-plus的Slider 滑块组件,主要功能就是根据滑块背景的不同颜色,滑动滑块过滤掉滑块范围以外背景颜色的要素。这里遇到一个大麻烦,本来以为很容易解决的,后面发现没有这么容易完成,就是滑块的背景颜色添加,这里想了好几种方式,最后还是只能使用原生js通过操作dom实现背景颜色的添加和上下两个滑块遮罩的添加(将要过滤的颜色范围遮盖掉)。核心代码如下:

watchEffect(() => {
  let [min, max] = sliderValue.value

  //为了添加滑块的遮罩,达到想要的效果(重点)
  nextTick(() => {
    let runway = document.getElementsByClassName('sliderLegend')?.[0]?.querySelectorAll('.el-slider__runway')[0]
    if (!runway.querySelector('.maxBar')) {
      let div = document.createElement('div')
      div.setAttribute('class', 'maxBar maskBar')
      runway.appendChild(div)
    }

    if (!runway.querySelector('.minBar')) {
      let div = document.createElement('div')
      div.setAttribute('class', 'minBar maskBar')
      runway.appendChild(div)
    }

    let maxMaskBar = document.querySelector('.maxBar')
    let minMaskBar = document.querySelector('.minBar')

    if (maxMaskBar) {
      maxMaskBar.style.height = new BigNumber(100).minus(max).toNumber() + '%'
    }

    if (minMaskBar) {
      minMaskBar.style.height = min + '%'
    }
  })
})

完整代码

/**
* sliderLegend.vue 可以拖动滑块过滤的图例
* @Author ZhangJun
* @Date  2024/1/19 9:36
**/
<template>
  <el-card class='slider-block absolute right-10 bottom-10'
           v-if='grades.values&&grades.values.length>0'
           style='z-index: 1000;'>
    <el-space direction='vertical' :size='20'>
      <el-text size='large' type='info'>{{ grades.desc }}{{ grades.unit }}</el-text>

      <div style='width: 60px;text-align: left;'>
        <el-slider ref='legendRef'
                   class='sliderLegend'
                   v-model='sliderValue'
                   @change='onChange'
                   :range='true'
                   vertical
                   :marks='marks'
                   v-bind='options' />
      </div>
    </el-space>
  </el-card>
</template>

<script setup>
import { ref, defineProps, computed, reactive, watchEffect, nextTick } from 'vue'
import BigNumber from 'bignumber.js'

const props = defineProps({
  gradesValues: { type: Array, default: () => ([]) },//分级的value数值
  gradesColors: { type: Array, default: () => ([]) },//分级的color数值(需要与gradesValues一一对应)
})

const emits = defineEmits(['update:modeValue'])

let legendRef = ref()

//当前滑块的值
let sliderValue = ref([0, 100])

//间隔数值
let interval = ref()

//为了获取真实数据和百分比之间的映射关系
let percentage2ValueDic = {}
let valueDic2Percentage = {}

/**
 * @Description 生成滑块的背景颜色
 * @Param colors 备选颜色集合
 * @Author ZhangJun
 * @Date  2024-01-19 01:43:56
 * @return void
 **/
let generationLinearGradient = computed(() => {
  let { colors } = grades
  let interval = new BigNumber(1).div(colors?.length)
  let temp = colors.map((color, index) => {
    let percentage = interval.times(index).times(100).toFixed(0) + '%'
    let rgba = `rgba(${color[0]},${color[1]},${color[2]},${color.length > 3 ? color[3] / 255 : 1})`
    if (index === 0) {
      return [rgba]
    } else {
      return [percentage, rgba]
    }
  })

  return `linear-gradient(to top,${temp.flat()})`
})

//刻度值
const marks = computed(() => {
  //清空
  percentage2ValueDic = {}
  valueDic2Percentage = {}
  let { values, unit } = grades
  interval.value = new BigNumber(1).div(values?.length - 1)
  let marks = {}
  values.forEach((value, index) => {
    let percentageVal = interval.value.times(index).times(100).toFixed(0)
    marks = { ...marks, [percentageVal]: `${value}` }
    //做映射使用
    percentage2ValueDic = { ...percentage2ValueDic, [percentageVal]: value }
    valueDic2Percentage = { ...valueDic2Percentage, [value]: percentageVal }
  })
  return marks
})

//分级数据
let grades = reactive({
  values: props.gradesValues,
  colors: props.gradesColors,
  unit: undefined,
  desc: '',
})

//默认的配置参数
let options = computed(() => {
  let { values } = grades
  let height = (values?.length - 1) * 40
  height = height > 300 ? 300 : height
  return {
    min: 0,
    max: 100,
    height: `${height}px`,
    step: interval.value.times(100).toFixed(0),
    showTooltip: false,
  }
})

/**
 * @Description 初始化当前control
 * @Param gradesData 分级参数
 * @Author ZhangJun
 * @Date  2024-01-22 09:38:17
 * @return void
 **/
function initControl(gradesData) {
  sliderValue.value = [0, 100]
  grades = Object.assign(grades, gradesData)
}

/**
 * @Description 获取数组里面最接近这个值的数
 * @Param arr 数组
 * @Param target 目标值
 * @Author ZhangJun
 * @Date  2024-01-19 07:19:21
 * @return void
 **/
function getClosestNumber(arr = [], target) {
  let minDistance = Math.abs(target - arr[0])
  let [closestNumber] = arr

  for (let i = 1; i < arr.length; i++) {
    let distance = Math.abs(target - arr[i])
    if (distance < minDistance) {
      minDistance = distance
      closestNumber = arr[i]
    }
  }

  return closestNumber
}

/**
 * @Description 滑块数值改变
 * @Param e 事件回调参数
 * @Author ZhangJun
 * @Date  2024-01-22 09:38:59
 * @return void
 **/
function onChange(e) {
  let [min, max] = e
  let arr = Object.keys(percentage2ValueDic)
  min = getClosestNumber(arr, min)
  max = getClosestNumber(arr, max)
  emits('update:modeValue', [percentage2ValueDic[min], percentage2ValueDic[max]])
}

watchEffect(() => {
  let [min, max] = sliderValue.value

  //为了添加滑块的遮罩,达到想要的效果(重点)
  nextTick(() => {
    let runway = document.getElementsByClassName('sliderLegend')?.[0]?.querySelectorAll('.el-slider__runway')[0]
    if (!runway.querySelector('.maxBar')) {
      let div = document.createElement('div')
      div.setAttribute('class', 'maxBar maskBar')
      runway.appendChild(div)
    }

    if (!runway.querySelector('.minBar')) {
      let div = document.createElement('div')
      div.setAttribute('class', 'minBar maskBar')
      runway.appendChild(div)
    }

    let maxMaskBar = document.querySelector('.maxBar')
    let minMaskBar = document.querySelector('.minBar')

    if (maxMaskBar) {
      maxMaskBar.style.height = new BigNumber(100).minus(max).toNumber() + '%'
    }

    if (minMaskBar) {
      minMaskBar.style.height = min + '%'
    }
  })
})

defineExpose({ initControl })

</script>

<style scoped lang='scss'>
::v-deep .el-slider__runway {
  background: v-bind(generationLinearGradient);

  .maskBar {
    width: 100%;
    height: auto;
    background: lightgrey;
    position: absolute;
    border-radius: 6px;
  }

  .maxBar {
    top: -3px;
  }

  .minBar {
    bottom: -3px;
  }
}

::v-deep .el-slider__bar {
  background: transparent;
}
</style>

效果

过滤后的效果

在这里插入图片描述

本来原理很简单,主要时间还是花费到了slider的背景颜色上,还要添加一个上下滑动的遮罩,才能将要过滤掉的颜色范围遮掉


本文为学习笔记,仅供参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/341222.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CmakeList教程

一、CmakeList介绍&#xff1a; cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。它会通过写的语句自动生成一个MakeFile,从而实现高效编译 二、CmakeList的常用指令 1.指定…

瑞_力扣LeetCode_101. 对称二叉树

文章目录 题目 101. 对称二叉树题解方式一 递归方式二 迭代 &#x1f64a; 前言&#xff1a;本文章为瑞_系列专栏之《刷题》的力扣LeetCode系列&#xff0c;主要以力扣LeetCode网的题进行解析与分享。本文仅供大家交流、学习及研究使用&#xff0c;禁止用于商业用途&#xff0c…

电脑 wifi 常断

问题 电脑wifi网络经常断。 详细问题 笔者使用笔记本电脑&#xff0c;发现每过三五分钟&#xff0c;wifi便会自动断开。 解决方案 步骤1、搜索框搜索设备管理器。 步骤2、找到网络适配器并点击。 步骤2、找到网络适配器菜单中的Wireless相关内容&#xff0c;右键&#x…

解读 EventBridge Transform:数据转换和处理的灵活能力

作者&#xff1a;木则 阿里云 EventBridge 提供了强大而灵活的事件总线服务&#xff0c;它可以连接应用程序、阿里云云服务和阿里云 Serverless 服务来快速构建 EDA&#xff08;Event-driven Architectures&#xff09;事件驱动架构&#xff0c;驱动应用与应用&#xff0c;应用…

VisualSVN Server下载安装和使用方法、服务器搭建、使用TortoiseSvn将项目上传到云端服务器、各种错误解决方法

VisualSVN Server下载安装和使用方法、服务器搭建、使用TortoiseSvn将项目上传到云端服务器、各种错误解决方法 0.写在前面00.电脑配置01.思路 1.VisualSVN Server下载安装01.下载02.安装03.电脑命名不能有中文04.制作VisualSVN Server快捷方式05.License limits exceeded, Som…

已解决Error:AttributeError: module ‘numpy‘ has no attribute ‘int‘.

文章目录 引言报错分析解决方案1&#xff1a;降低NumPy版本解决方案2&#xff1a;更改NumPy源码 结尾 引言 在Python编程中&#xff0c;NumPy是一个不可或缺的库&#xff0c;尤其在处理大规模数值计算时。但即使是这个强大的工具&#xff0c;也可能在使用过程中遇到问题。其中…

接口自动化测试框架开发(pytest+allure+aiohttp+ 用例自动生成)

近期准备优先做接口测试的覆盖&#xff0c;为此需要开发一个测试框架&#xff0c;经过思考&#xff0c;这次依然想做点儿不一样的东西。 接口测试是比较讲究效率的&#xff0c;测试人员会希望很快能得到结果反馈&#xff0c;然而接口的数量一般都很多&#xff0c;而且会越来越…

Android开发之部署opencv4

1 新建一个空项目 不再多说 2从官网下载opencv https://opencv.org/releases/ 下载opencv-4.9.0-android-sdk 3 导入模块 点击file->new->Import Module选择解压之后的opencv-android-sdk文件夹中的SDk文件夹&#xff0c;并将:sdk修改为:opencv&#xff08;我的已安…

Linux中Makefile用法及变量

一、介绍 1.Makefile概述 (1)make是一个命令工具&#xff0c;是一个解释makefile中指令的命令工具&#xff0c;一般来说&#xff0c;大多数的IDE 都有这个命令&#xff0c;比如&#xff1a;Delphi的make&#xff0c;Visual C的nmake&#xff0c;Linux下GNU的make (…

工业相机+镜头选型及靶面、焦距计算等相关详解

工业相机镜头选型及靶面、焦距计算等相关详解 着重讲述相机的各个参数及使用意义总结相机镜头选型主要参数的推理计算 0. 工业相机相关概念简介 相机与镜头一览 工业相机与镜头实物图如下图所示&#xff1a; 常见的相机有两种供电方式&#xff1a;一种是电源线供电&#xff0…

怎么抹掉 Macbook系统 并将它还原为出厂设置

抹掉 Mac 并将它还原为出厂设置 借助“抹掉所有内容和设置”这项功能&#xff0c;你可以快速安全地抹掉所有设置、数据和 App&#xff0c;同时保留当前安装的操作系统。 使用“抹掉所有内容和设置” 这项功能要求装有 macOS Monterey 或更高版本&#xff0c;且使用搭载 Apple 芯…

计算机毕业设计 基于SpringBoot的律师事务所案件管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Linux的一些快捷键(hot keyboard)

Ctrl Alt t&#xff1a;打开bash&#xff08;就是命令框窗口&#xff09; Ctrl Alt F3~F6&#xff1a;打开tty终端&#xff08;纯命令行终端&#xff0c;每个Linux发行版不相同&#xff0c;我的是Ubuntu20版&#xff09; Alt F4&#xff1a;关闭当前窗口&#xff08;Windo…

快乐学Python,使用爬虫爬取电视剧信息,构建评分数据集

在前面几篇文章中&#xff0c;我们了解了Python爬虫技术的三个基础环节&#xff1a;下载网页、提取数据以及保存数据。 这一篇文章&#xff0c;我们通过实际操作来将三个环节串联起来&#xff0c;以国产电视剧为例&#xff0c;构建我们的电视剧评分数据集。 1、需求描述 收集…

NOC总线(2)

1. NoC的路由 在NoC交换信息时&#xff0c;需要确定从源节点到目标节点所经过的路径&#xff0c;这时就需要路由算法来确定该路径。路由算法分为静态路由算法和动态路由算法两种。 静态路由算法对于两节点之间的路径是固定的&#xff0c;结构简单&#xff0c;便于硬件实…

FPGA中跨时钟域传数据——(1)单bit脉冲

FPGA中跨时钟域传数据——&#xff08;1&#xff09;单bit脉冲 亚稳态模型由快时钟传到慢时钟由慢时钟传到快时钟 亚稳态模型 必须在建立时间和保持时间内&#xff0c;数据不变化&#xff0c;否则会产生亚稳态。 由快时钟传到慢时钟 在快时钟里面进行数据展宽&#xff08;…

时间序列预测 — CNN-LSTM-Attention实现多变量负荷预测(Tensorflow):多变量滚动

专栏链接&#xff1a;https://blog.csdn.net/qq_41921826/category_12495091.html 专栏内容 ​ 所有文章提供源代码、数据集、效果可视化 ​ 文章多次上领域内容榜、每日必看榜单、全站综合热榜 ​ ​ ​ ​ ​ ​ ​ 时间序列预测存在的问题 ​ 现有的大量方法没有真正的预测未…

ELK+Filebeat 部署实验

Filebeat是轻量级的开源日志文件数据搜集器。通常在需要采集数据的客户端安装 Filebeat&#xff0c;并指定目录与日志格式&#xff0c;Filebeat 就能快速收集数据&#xff0c;并发送给 logstash 进行解析&#xff0c;或是直接发给 Elasticsearch 存储&#xff0c;性能上相比运行…

CentOS 7 安装配置MySQL

目录 一、安装MySQL​编辑​编辑 1、检查MySQL是否安装及版本信息​编辑 2、卸载 2.1 rpm格式安装的mysql卸载方式 2.2 二进制包格式安装的mysql卸载 3、安装 二、配置MySQL 1、修改MySQL临时密码 2、允许远程访问 2.1 修改MySQL允许任何人连接 2.2 防火墙的问题 2…

AnimatedDrawings:让绘图动起来

老样子&#xff0c;先上图片和官网。这个项目是让绘制的动画图片动起来&#xff0c;还能绑定人体的运动进行行为定制。 快速开始 1. 下载代码并进入文件夹&#xff0c;启动一键安装 git clone https://github.com/facebookresearch/AnimatedDrawings.gitcd AnimatedDrawingspip…