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

news2024/11/24 19:00:15

前言

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

技术核心

说到过滤要素,第一时间想到的就是滑块组件,这里我们选择了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的背景颜色上,还要添加一个上下滑动的遮罩,才能将要过滤掉的颜色范围遮掉


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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

burp靶场--业务逻辑漏洞

burp靶场–业务逻辑漏洞 https://portswigger.net/web-security/logic-flaws#what-are-business-logic-vulnerabilities ### 什么是业务逻辑漏洞&#xff1f; 业务逻辑漏洞是应用程序设计和实现中的缺陷&#xff0c;允许攻击者引发意外行为。这可能使攻击者能够操纵合法功能来…

德思特干货|如何使用SBench 6对数字化仪采集信号进行处理?(三)——快速傅立叶变换(FFT)

来源&#xff1a;德思特测量测试 德思特干货&#xff5c;如何使用SBench 6对数字化仪采集信号进行处理&#xff1f;&#xff08;三&#xff09;——快速傅立叶变换&#xff08;FFT&#xff09; 原文链接&#xff1a;https://mp.weixin.qq.com/s/mYS1iDXFNVfReCGGtF78mw 欢迎关…

Ubuntu用gparted重新分配空间

ubuntu系统使用过程中安装系统时预先留的空间不够使用怎么办&#xff1f; 这么办&#xff01; 首先 使用df -h 查看当前空间使用情况 已经分配的空间重新规划 &#xff1f; 先将已分配的空间中的多余空间分离出来&#xff1b; 假设我想将挂载点/home下的一部分空间分给挂载…

用户资源(菜单)控制学习使用

效果图 第一步 需要再定义常量资源 //信访听证 资源前缀public static final String RESPREFIX_MODULE_XINFTZ_"module_xinftz_";//听证专家库public static final ConstantItem RES_MODULE_XINFTZ_TINGZZJK new ConstantItem(RESPREFIX_MODULE_XINFTZ_ "tin…

SpringCloud中服务间通信(应用间通信)-亲测有效-源码下载-连载2

1、微服务概述 本案例主要解决微服务之间的相互调用问题 如果已经理解什么是微服务&#xff0c;可以直接跳到实战。 本案例采用springBoot3.1.7springCloud2022.0.4版本测试 本案例使用springboot2.7.x版本测试代码相同 1、微服务是分布式架构&#xff0c;那么为什么要需要…

Unity中URP下的SimpleLit的 BlinnPhong高光反射计算

文章目录 前言一、回顾Blinn-Phong光照模型1、Blinn-Phong模型&#xff1a; 二、URP下的SimpleLit的 BlinnPhong1、输入参数2、程序体计算 前言 在上篇文章中&#xff0c;我们分析了 URP下的SimpleLit的 Lambert漫反射计算。 Unity中URP下的SimpleLit的 Lambert漫反射计算 我…

计算机网络自顶向下Wireshark labs1-Intro

Wireshark labs1 实验文档&#xff1a;http://www-net.cs.umass.edu/wireshark-labs/Wireshark_Intro_v8.0.pdf 介绍 加深对网络协议的理解通常可以通过观察协议的运行和不断调试协议来大大加深&#xff0c;具体而言&#xff0c;就是观察两个协议实体之间交换的报文序列&…

DEB方式安装elastic search7以及使用

参考&#xff1a;https://www.cnblogs.com/anech/p/15957607.html 1、安装elastic search7 #手动下载安装 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.1-amd64.deb wget https://artifacts.elastic.co/downloads/elasticsearch/elastics…

R语言简介

1.R语言 R语言是一种数学编程语言&#xff0c;主要用于统计分析、绘图和数据挖掘。 2.R语言特点 免费、开源&#xff0c;兼容性好&#xff08;Windows、MacOS或Linux)。具有多种数据类型&#xff0c;如向量、矩阵、因子、数据集等常用数据结构。多用于交互式数据分析&#x…

Linux配置yum源以及基本yum指令

文章目录 一、yum介绍二、什么是软件包三、配置yum源四、一键配置yum源【三步走】五、yum指令搜索软件安装软件卸载软件 六、其他yum指令更新内核更新软件更新指定软件显示所有可更新的软件清单卸载指定包并自动移除依赖包删除软件包&#xff0c;以及软件包数据和配置文件 一、…

灵眸边缘计算产品学习

EASY EAI灵眸科技 | 让边缘AI落地更简单 (easy-eai.com) 产品简介 支持4路1080P30fps视频流采集&#xff0c;四核CPU1.5GHz与2Tops AI边缘算力能力。集成有以太网、Wi-Fi、4G等网络通信外设&#xff1b;RS232、RS485、UART等本地通信接口。HDMI显示屏接口、音频输入输出等交互…

打造出色的 Prometheus 监控系统,看完后薪资翻倍?

一、监控概念&误区 监控是管理基础设施和业务的核心工具&#xff0c;监控应该和应用程序一起构建和部署&#xff0c;没有监控&#xff0c;将无法了解你的系统运行环境&#xff0c;进行故障诊断&#xff0c;也无法阻止提供系统性的性能、成本和状态等信息。 误区&#xff1…

【江科大】STM32:(超级详细)定时器输出比较

文章目录 输出比较单元特点 高级定时器&#xff1a;均有4个通道 PWM简介PWM&#xff08;Pulse Width Modulation&#xff09;脉冲宽度调制输出比较通道PWM基本结构基本定时器 参数计算捕获/比较通道的输出部分详细介绍如下&#xff1a; 舵机介绍硬件电路 直流电机介绍&#xff…

C# 使用System.Threading.Timer 实现计时器

写在前面 以往一般都是用 System.Timers.Timer 来做计时器&#xff0c;而 System.Threading.Timer 也可以实现计时器功能&#xff0c;并且还可以配置首次执行间隔&#xff0c;在功能上比System.Timers.Timer更加丰富&#xff1b;根据这个特性就可以实现按指定时间间隔对委托进…

JDX图片识别工具1.0版本发布啦

软件介绍 软件核心功能软件界面软件下载软件教程 软件核心功能 工作当中经常处理大量的图片&#xff0c;网上搜索的工具都无法满足需求&#xff0c;因此自己研发批量图片识别工具。 目前还是内测版&#xff0c;1.0版本主要包含如下特性&#xff1a; 批量识别图片&#xff0c…

前端JS加密与Buspsuite的坦诚相待

前端JS加密测试场景下的困惑 在渗透测试过程中经常会遇到JS前端加密的场景&#xff0c;假如不借助任何工具的情况下&#xff0c;我们一般是把JS代码进行扣取&#xff0c;本地进行加解密生成Payload&#xff0c;然后在Burpsuite里进行Payload替换。这种方式就存在一个很明显的问…

自然语言处理--双向匹配算法

自然语言处理作业1--双向匹配算法 一、概述 双向匹配算法是一种用于自然语言处理的算法&#xff0c;用于确定两个文本之间的相似度或匹配程度。该算法通常使用在文本对齐、翻译、语义匹配等任务中。 在双向匹配算法中&#xff0c;首先将两个文本分别进行处理&#xff0c;然后…

使用Docker部署Apache Superset结合内网穿透实现远程访问本地服务

文章目录 前言1. 使用Docker部署Apache Superset1.1 第一步安装docker 、docker compose1.2 克隆superset代码到本地并使用docker compose启动 2. 安装cpolar内网穿透&#xff0c;实现公网访问3. 设置固定连接公网地址 前言 Superset是一款由中国知名科技公司开源的“现代化的…

操作系统导论-课后作业-ch14

1. 代码如下&#xff1a; #include <stdio.h> #include <stdlib.h>int main() {int *i NULL;free(i);return 0; }执行结果如下&#xff1a; 可见&#xff0c;没有任何报错&#xff0c;执行完成。 2. 执行结果如下&#xff1a; 3. valgrind安装使用参考&a…

决策树的基本构建流程

决策树的基本构建流程 决策树的本质是挖掘有效的分类规则&#xff0c;然后以树的形式呈现。 这里有两个重点&#xff1a; 有效的分类规则&#xff1b;树的形式。 有效的分类规则&#xff1a;叶子节点纯度越高越好&#xff0c;就像我们分红豆和黄豆一样&#xff0c;我们当然…