当前位置: 首页 > news >正文

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 } = gradeslet 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 } = gradesinterval.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 } = gradeslet height = (values?.length - 1) * 40height = height > 300 ? 300 : heightreturn {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] = arrfor (let i = 1; i < arr.length; i++) {let distance = Math.abs(target - arr[i])if (distance < minDistance) {minDistance = distanceclosestNumber = arr[i]}}return closestNumber
}/*** @Description 滑块数值改变* @Param e 事件回调参数* @Author ZhangJun* @Date  2024-01-22 09:38:59* @return void**/
function onChange(e) {let [min, max] = elet 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的背景颜色上,还要添加一个上下滑动的遮罩,才能将要过滤掉的颜色范围遮掉


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

相关文章:

  • uniapp开发小程序—scroll-view实现内容滚动时, 标题也滚动
  • ESP32-HTTP_webServer库(Arduino)
  • Cacti 前台SQL注入漏洞复现(CVE-2023-39361)
  • Unity中URP下的 额外灯 逐像素光 和 逐顶点光
  • props传值
  • 自然语言处理的崛起:从初步分析到深度理解
  • PLC从HTTP服务端获取JSON文件,解析数据到寄存器
  • Linux编辑器---vim
  • 2.2.1.1-一个关于定投的故(姿)事(势)
  • CloudPanel RCE漏洞复现(CVE-2023-35885)
  • 探索设计模式的魅力:一次设计,多次利用,深入理解原型模式的设计艺术
  • EasyExcelFactory 导入导出功能的实战使用
  • 《数据结构》第七章:树和森林
  • 解开缺省参数与函数重载的衣裳
  • 超过GPT3.5?Mixtral 8*7B 模型结构分析
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • Angular Elements 及其运作原理
  • canvas绘制圆角头像
  • es6(二):字符串的扩展
  • Fundebug计费标准解释:事件数是如何定义的?
  • IDEA常用插件整理
  • Median of Two Sorted Arrays
  • mysql外键的使用
  • 服务器从安装到部署全过程(二)
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 规范化安全开发 KOA 手脚架
  • 力扣(LeetCode)965
  • 强力优化Rancher k8s中国区的使用体验
  • 如何利用MongoDB打造TOP榜小程序
  • 算法-插入排序
  • ​secrets --- 生成管理密码的安全随机数​
  • #162 (Div. 2)
  • (1)(1.11) SiK Radio v2(一)
  • (4)Elastix图像配准:3D图像
  • (6)设计一个TimeMap
  • (pytorch进阶之路)扩散概率模型
  • (八十八)VFL语言初步 - 实现布局
  • (二)pulsar安装在独立的docker中,python测试
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (六)Hibernate的二级缓存
  • (三)c52学习之旅-点亮LED灯
  • (算法)Game
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • .aanva
  • .axf 转化 .bin文件 的方法
  • .equals()到底是什么意思?
  • .gitignore文件设置了忽略但不生效
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .Net程序帮助文档制作
  • /bin/rm: 参数列表过长"的解决办法
  • /run/containerd/containerd.sock connect: connection refused
  • ?php echo ?,?php echo Hello world!;?