基于JavaScript实现数值型坐标轴刻度计算算法(echarts的y轴刻度计算)

目录
  • 前言
  • 算法描述
  • 代码
  • ts版本(2021/3/10补充)
  • 结语

前言

因实习的公司是做大数据的,而我的工作刚好又是需要绘制一些数据图表的。绘制图表有许多现成的组件可以使用,但是要想达到产品所需要的效果,只靠组件内部的一些功能是不太够的。一些细腻的要求必须在掌握组件原理方法的情况下,自己去写算法来完成。例如,本文要说的这个刻度计算算法,开始正文之前,我先描述遇到的问题。
echarts自身的刻度计算有时候并不好用,例如有时候你希望让图表只有5条刻度线,即分成4段,echarts提供了一个参数叫splitNumber,把splitNumber设为4可以让图表尽量地分成4段,然而当数据波动较大时,echarts会自动增加分割的段数,即即使大部分数据都能正常分出4段刻度,但仍有少部分数据实际分出的段数可能不止4段。

如下面这样:

因此我们得出一个结论,echarts的splitNumber只是预估的分割段数。如果我们需要强制把刻度区间分为4段,则需要我们自己去写算法计算刻度。另外,即使段数正确的情况下,echarts自动计算出的刻度也可能存在区间过大,数据差异不明显的情况,如下面的图片,因为刻度区间太大,导致各个数据看起来像是差不多大的,看不出差异:

另外,echarts自动计算出的刻度也有一些其他的问题,例如当图表在柱状图和堆叠图中切换时,堆叠图可能出现刻度溢出问题。不过堆叠图的刻度计算这里就先不说明了,下面开始正文吧。

算法描述

刻度计算的算法之前我之前也写了一版,解决了分割段数的问题,但是仍无法解决刻度区间过大的问题。之前那一版算法的主要思想是取近似值,分别取最大值和最小值的最小近似整值得到刻度,虽然不是最优的算法,但是在构思和调整算法的时候我也学到了不少东西,而这一版的算法是在我们技术老大的点拨下结合网上的一些文章和项目的需求而写出来的,算法如下

要求: 根据一组数的最大值、最小值来确定刻度值,确定刻度的最大值maxi、最小值mini和刻度间隔interval。当出现异号数据时可选择正负两边刻度是否需要对称,当存在异号数据时要求其中一条刻度分割线必须在0刻度上,可以选择是否允许段数误差。

  • 确定分割段数splitNumber和魔数数组magic = [10,15,20,25,30,40,50,60,70,80,90,100];
  • 从目标数组arr中算出最大值max和最小值min,确定初始间隔大小 tempGap = (max-min)/splitNumber;
  • 设tempGap除以一个倍数multiple后,刚好处于魔数数组的区间[10,100]中,记录倍数multiple;
  • 从魔数数组中取出第一个大于tempGap缩放值的魔数,用 魔数*multiple当做理想刻度间隔(estep)进行第一次计算,计算出max和min的邻近刻度maxi和mini,如果允许分割段数误差,则直接结束运算,取interval=estep;
  • 当刻度需要正负两边对称且存在异号数据时,取maxi和mini中绝对值大的一方,将其相反数赋值给另外一方,计算interval=(maxi-mini)/splitNumber,结束运算;
  • 当正负刻度不需要对称或不存在异号数据时,判断实际分割段数是否等于splitNumber,如果不相等,则重新取较大的魔数进行运算,当魔数取完或者分割段数相等时结束运算,得出interval=(maxi-mini)/splitNumber.

代码

算法采用javascript语言描述,因为图表的绘制在前端完成:

/*
	刻度计算算法,基于魔术数组 [10, 15, 20, 25, 30, 40, 50, 60, 70, 80, 90, 100];
	解释:魔数数组是理想间隔数组,即我们希望每个刻度的间隔都是魔数数组中某个数的整数倍。(准确的来说是整10倍)
*/
//新增,解决js的浮点数存在精度问题,在计算出最后结果时可以四舍五入一次,因为刻度太小也没有意义,所以这里忽略设置精度为8位
function fixedNum(num){
	if((""+num).indexOf('.')>=0) num = parseFloat(num.toFixed(8));
	return num;
}
//1.初始化
var symmetrical = false;//是否要求正负刻度对称。默认为false,需要时请设置为true
var deviation = false;//是否允许误差,即实际分出的段数不等于splitNumber
var magic = [10, 15, 20, 25, 30, 40, 50, 60, 70, 80, 90, 100];//魔数数组经过扩充,放宽魔数限制避免出现取不到魔数的情况。
var arr = [1230, 320, 20, 304, 102, 234];//测试数据
var max,min,splitNumber;
splitNumber = 4;//理想的刻度间隔段数,即希望刻度区间有多少段
max = Math.max.apply(null,arr);//调用js已有函数计算出最大值
min = Math.min.apply(null,arr);//计算出最小值
//2.计算出初始间隔tempGap和缩放比例multiple
var tempGap = (max - min) / splitNumber;//初始刻度间隔的大小。
//设tempGap除以multiple后刚刚处于魔数区间内,先求multiple的幂10指数,例如当tempGap为120,想要把tempGap映射到魔数数组(即处理为10到100之间的数),则倍数为10,即10的1次方。
var multiple = Math.floor(Math.log10(tempGap)-1);//这里使用Math.floor的原因是,当Math.log10(tempGap)-1无论是正负数都需要向下取整。不能使用parseInt或其他取整逻辑代替。
multiple = Math.pow(10,multiple);//刚才是求出指数,这里求出multiple的实际值。分开两行代码避免有人看不懂
//3.取出邻近较大的魔数执行第一次计算
var tempStep = tempGap / multiple;//映射后的间隔大小
var estep;//期望得到的间隔
var lastIndex = -1;//记录上一次取到的魔数下标,避免出现死循环
for(var i = 0; i < magic.length;i++){
	if(magic[i]>tempStep){
		estep = magic[i]*multiple;//取出第一个大于tempStep的魔数,并乘以multiple作为期望得到的最佳间隔
		break;
	}
}
//4.求出期望的最大刻度和最小刻度,为estep的整数倍
var maxi,mini;
function countDegree(estep){
	//这里的parseInt是我无意中写出来的,本来我是想对maxi使用Math.floor,对mini使用Math.ceil的。这样能向下取到邻近的一格,不过后面发现用parseInt好像画出来图的比较好看
	maxi = parseInt(max/estep+1) * estep;//最终效果是当max/estep属于(-1,Infinity)区间时,向上取1格,否则取2格。
	mini = parseInt(min/estep-1) * estep;//当min/estep属于(-Infinity,1)区间时,向下取1格,否则取2格。
	//如果max和min刚好在刻度线的话,则按照上面的逻辑会向上或向下多取一格
	if(max===0) maxi = 0;//这里进行了一次矫正,优先取到0刻度
	if(min===0) mini = 0;
	if(symmetrical&&maxi*mini<0){//如果需要正负刻度对称且存在异号数据
		var tm = Math.max(Math.abs(maxi),Math.abs(mini));//取绝对值较大的一方
		maxi = tm;
		mini = -tm;
	}
}
countDegree(estep);
if(deviation){//如果允许误差,即实际分段数可以不等于splitNumber,则直接结束
	var interval = fixedNum(estep);
	console.log(maxi,mini,interval);
	return;
}
//5.当正负刻度不对称且0刻度不在刻度线上时,重新取魔数进行计算//确保其中一条分割线刚好在0刻度上。
else if(!symmetrical||maxi*mini>0){
	outter:do{
		//计算模拟的实际分段数
		var tempSplitNumber = Math.round((maxi-mini)/estep);
		//当趋势单调性发生变化时可能出现死循环,需要进行校正
		if((i-lastIndex)*(tempSplitNumber-splitNumber)<0){//此处检查单调性变化且未取到理想分段数
			//此处的校正基于合理的均匀的魔数数组,即tempSplitNumber和splitNumber的差值较小如1和2,始终取大刻度
			while(tempSplitNumber<splitNumber){//让maxi或mini增大或减少一个estep直到取到理想分段数
				if((mini-min)<=(maxi-max)&&mini!=0||maxi==0){//在尽量保留0刻度的前提下,让更接近最值的一边扩展一个刻度
					mini-=estep;
				}else{
					maxi+=estep;
				}
				tempSplitNumber++;
				if(tempSplitNumber==splitNumber)
					break outter;
			}
		}
		//当魔数下标越界或取到理想分段数时退出循环
		if(i>=magic.length-1|| i<=0 || tempSplitNumber==splitNumber) break;
		//记录上一次的魔数下标
		lastIndex = i;
		//尝试取符合趋势的邻近魔数
		if(tempSplitNumber>splitNumber) estep = magic[++i]*multiple;
		else estep = magic[--i]*multiple;
		//重新计算刻度
		countDegree(estep);
	}while(tempSplitNumber!=splitNumber);
}
//6.无论计算始终把maxi-mini分成splitNumber段,得到间隔interval。不过前面的算法已经尽量的保证刻度最优了,即interval接近或等于理想刻度estep。
maxi = fixedNum(maxi);
mini = fixedNum(mini);
var interval = fixedNum((maxi-mini)/splitNumber);
console.log(maxi,mini,interval);

代码运行效果:

1.如果不处理小数误差,且强制分为4段,出来的效果是这样的(20190722版):

2.处理了小数误差,并允许刻度误差出来的效果是这样的(20190723版)

可以看出:

  • 采用基于魔数数组的新算法计算出的刻度区间是紧挨着最大值和最小值的,算是差强人意。
  • js中浮点数的精度问题是我们在设计一些通用性的算法时需要注意的,图片右边可以看到,当数据幅度较小时,算出的min和interval是存在误差的。
  • 图片左边的刻度的精确度处理是我写的逻辑,当数据为非纯小数时最多只精确到3位小数,纯小数时精确到8位,避免出现刻度过长,echarts并没有自带这个功能。

再附上一张存在异号数据时的效果和一张需要正负刻度对称的效果:

可以看出:

  • 正负刻度不对称且其中一条分割线刚好在0刻度上
  • y轴刻度的40K其实是40000的缩写,算法也是要自己写的,echarts没有提供这个功能。

ts版本(2021/3/10补充)

export interface ScaleOption {
    /**
     * 数据最大值
     *
     * @type {(number | null)}
     * @memberof ScaleOption
     */
    max: number | null;
    /**
     * 数据最小值
     *
     * @type {(number | null)}
     * @memberof ScaleOption
     */
    min: number | null;
    /**
     * 预期分成几个区间
     *
     * @type {number}
     * @memberof ScaleOption
     */
    splitNumber?: number;
    /**
     * 存在异号数据时正负区间是否需要对称
     *
     * @type {boolean}
     * @memberof ScaleOption
     */
    symmetrical?: boolean;
    /**
     * 是否允许实际分成的区间数有误差
     *
     * @type {boolean}
     * @memberof ScaleOption
     */
    deviation?: boolean;
    /**
     * 是否优先取到0刻度
     *
     * @type {boolean}
     * @memberof ScaleOption
     */
    preferZero?: boolean;
}
export interface ScaleResult {
    max?: number;
    min?: number;
    interval?: number;
    splitNumber?: number;
}

// 双精度浮点数有效数字为15位
const maxDecimal = 15;
/**
 * 解决js的浮点数存在精度问题,在计算出最后结果时可以四舍五入一次,刻度太小也没有意义
 *
 * @export
 * @param {(number | string)} num
 * @param {number} [decimal=8]
 * @returns {number}
 */
export function fixedNum(num: number | string, decimal: number = maxDecimal): number {
    let str: string = "" + num;
    if (str.indexOf(".") >= 0) str = Number.parseFloat(str).toFixed(decimal);
    return Number.parseFloat(str);
}

/**
 * 判断非Infinity非NaN的number
 *
 * @export
 * @param {*} num
 * @returns {num is number}
 */
export function numberValid(num: any): num is number {
    return typeof num === "number" && Number.isFinite(num);
}

/**
 * 计算理想的刻度值,刻度区间大小一般是[10, 15, 20, 25, 30, 40, 50, 60, 70, 80, 90, 100]中某个数字的整10倍
 *
 * @export
 * @param {ScaleOption} option
 * @returns {ScaleResult}
 */
export function scaleCompute(option: ScaleOption): ScaleResult {
    option = {
        max: null,
        min: null,
        splitNumber: 4, // splitNumber建议取4或者5等这种容易被整除的数字
        symmetrical: false,
        deviation: false,
        preferZero: true,
        ...option,
    };
    const magics: number[] = [10, 15, 20, 25, 30, 40, 50, 60, 70, 80, 90, 100, 150]; // 加入150形成闭环
    // tslint:disable-next-line: prefer-const
    let { max : dataMax, min: dataMin, splitNumber, symmetrical, deviation, preferZero } = option;
    if (!numberValid(dataMax) || !numberValid(dataMin) || dataMax < dataMin) {
        return { splitNumber };
    } else if (dataMax === dataMin && dataMax === 0) {
        return {
            max: fixedNum(magics[0] * splitNumber),
            min: dataMin,
            interval: magics[0],
            splitNumber,
        };
    } else if (dataMax === dataMin) {
        preferZero = true;
    }
    if (!numberValid(splitNumber) || splitNumber <= 0) splitNumber = 4;
    if (preferZero && dataMax * dataMin > 0) {
        if (dataMax < 0) dataMax = 0;
        else dataMin = 0;
    }
    const tempGap: number = (dataMax - dataMin) / splitNumber;
    let multiple: number = Math.floor(Math.log10(tempGap) - 1); // 指数
    multiple = Math.pow(10, multiple);
    const tempStep: number = tempGap / multiple;
    let expectedStep: number = magics[0] * multiple;
    let storedMagicsIndex: number = -1;
    let index: number; // 当前魔数下标
    for (index = 0; index < magics.length; index++) {
        if (magics[index] > tempStep) {
            expectedStep = magics[index] * multiple; // 取出第一个大于tempStep的魔数,并乘以multiple作为期望得到的最佳间隔
            break;
        }
    }
    let axisMax: number = dataMax;
    let axisMin: number = dataMin;
    function countDegree(step: number): void {
        axisMax = parseInt("" + (dataMax / step + 1)) * step; // parseInt令小数去尾 -1.8 -> -1
        axisMin = parseInt("" + (dataMin / step - 1)) * step;
        if (dataMax === 0) axisMax = 0; // 优先0刻度
        if (dataMin === 0) axisMin = 0;
        if (symmetrical && axisMax * axisMin < 0) {
            const tm: number = Math.max(Math.abs(axisMax), Math.abs(axisMin));
            axisMax = tm;
            axisMin = -tm;
        }
    }
    countDegree(expectedStep);
    if (deviation) {
        return {
            max: fixedNum(axisMax),
            min: fixedNum(axisMin),
            interval: fixedNum(expectedStep),
            splitNumber: Math.round((axisMax - axisMin) / expectedStep),
        };
    } else if (!symmetrical || axisMax * axisMin > 0) {
        let tempSplitNumber: number;
        out: do {
            tempSplitNumber = Math.round((axisMax - axisMin) / expectedStep);
            if ((index - storedMagicsIndex) * (tempSplitNumber - splitNumber) < 0) { // 出现死循环
                while (tempSplitNumber < splitNumber) {
                    if ((axisMin - dataMin <= axisMax - dataMax && axisMin !== 0) || axisMax === 0) {
                        axisMin -= expectedStep;
                    } else {
                        axisMax += expectedStep;
                    }
                    tempSplitNumber++;
                    if (tempSplitNumber === splitNumber) break out;
                }
            }
            if (index >= magics.length - 1 || index <= 0 || tempSplitNumber === splitNumber) break;
            storedMagicsIndex = index;
            if (tempSplitNumber > splitNumber) expectedStep = magics[++index] * multiple;
            else expectedStep = magics[--index] * multiple;
            countDegree(expectedStep);
        } while (tempSplitNumber !== splitNumber);
    }
    axisMax = fixedNum(axisMax);
    axisMin = fixedNum(axisMin);
    const interval: number = fixedNum((axisMax - axisMin) / splitNumber);
    return {
        max: axisMax,
        min: axisMin,
        interval,
        splitNumber,
    };
}

结语

好久没有写博客,可能是最近比较忙,如果有空的话其实前端有很多东西都可以写一下,今天写这个博客是因为文章篇幅较小,而且我刚好在检查算法,另外这个算法比较有参考意义,就忙里偷闲写出来给大家看看,也方便我自己以后查阅。

到此这篇关于基于JavaScript实现数值型坐标轴刻度计算算法(echarts的y轴刻度计算需求)的文章就介绍到这了,更多相关JS坐标轴刻度算法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JavaScript之ECharts用法讲解

    前面做项目时用到ECharts,今天特此整理一下,作为笔记,同时希望帮助更多人. 首先简单介绍一下,ECharts是一个纯JavaScript图表库,底层依赖于轻量级的Canvas类库ZRender,基于BSD开原协议,是一款非常优秀的可视化前端框架. 官网地址:http://echarts.baidu.com/ 1.首先在官网 选择合适的下载版本        http://echarts.baidu.com/download.html 2.引入Echarts <script src="

  • Echarts.js无法引入问题解决方案

    使用echart卡在引入包的问题上了. 到github下载的js一直引入不了.注意是引入dirt文件夹下的echarts.js 把这个文件夹放入工程即可.其余都不用. 代码部分简单的一匹: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>ECharts</title> <!-- 引入 echarts.js --> <scrip

  • vue.js集成echarts时遇到的一些问题总结

    前言 最近在做Beetlex的数据分析平台,在开发这个产品过程中涉及到大量的数据图表展示功能:由于产品前端使用的是vuejs开发,所以在集成echarts或多或少会碰到一些问题,在这里主要讲解一下碰到的问题和解决方法. 在讲解之前先分享一下实际使用效果.具体可以查看 http://data.beetlex.io 控件ID 在vuejs中往往会对常用的功能进行组件封装,同样为了让不同图表复用所以也封装成组件来使用.在这个封装过程存在一个问题就是图表元素DIV的ID问题,所以组件建构建图表DIV的I

  • Echarts.js实现水滴球和海洋效果

    一.水滴球 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- 引入 ECharts 文件 --> <script src="echarts.min.js"></script> <script src="echarts-liquidfill.js"></script> <

  • vue.js中使用echarts实现数据动态刷新功能

    在vue使用echarts时,可能会遇到这样的问题,就是直接刷新浏览器,或者数据变化时,echarts不更新? 这是因为Echarts是数据驱动的,这意味着只要我们重新设置数据,那么图表就会随之重新渲染,这是实现本需求的基础.我们再设想一下, 如果想要支持数据的自动刷新,必然需要一个监听器能够实时监听到数据的变化然后告知Echarts重新设置数据. 所幸Vue为我们提供了==watcher==功能,通过它我们可以很方便的实现上述功能: watch:{ option:function(newval

  • JS使用canvas技术模仿echarts柱状图

    canvas 画布是html5中新增的标签,可以通过js操作 canvas 绘图 API在网页中绘制图像. 百度开发了一个开源的可视化图表库ECharts,功能非常强大,可以实现折线图.柱状图.散点图.饼图.K线图.地图等多种图表.很多项目都有使用过ECharts开发过图表功能. 本实例教程使用原生js教你开发一个仿ECharts的柱状图.学习本教程之前,读者需要具备html和css技能,同时需要有简单的JavaScript基础. 按照ECharts的开发方法,图表都是生成在一个HTML元素中.

  • Javascript Echarts空气质量地图效果详解

    我们要先把空气质量数据和地图数据结合起来: 地图数据有name这个属性 我们的不同城市空气质量也有name这个属性,这两个属性是一样的,都叫name,所以我们可以把他们关联起来: var airData = [ { name: '北京', value: 39.92 }, { name: '天津', value: 39.13 }, { name: '上海', value: 31.22 }, { name: '重庆', value: 66 }, { name: '河北', value: 147 },

  • JavaScript数据可视化:ECharts制作地图

    目录 概述 注意事项 一. 使用方式 二. 实现步骤 初步实现代码 效果: geo常见配置 添加上面配置之后的效果图: 显示某一个省份(河南省) 效果 不同区域显示不同颜色 地图和散点图的结合 总结 概述 地图在我们日常的数据可视化分析中是很常见的一种展示手段,不仅美观而且很大气.尤其是在大屏展示中更是扮演着必不可缺的角色 注意事项 一. 使用方式 1.百度地图API(高德地图API) 需要申请百度API 2.矢量地图 需要准备矢量地图数据 二. 实现步骤 1.ECharts最基本的代码结构 引

  • 如何利用js读取excel文件并绘制echarts图形

    目录 1.场景描述 2.需求描述 3.功能实现 4.尾言 1.场景描述 通常来说,前端要拿到excel数据,都是先上传存储数据库,然后再请求后端接口,获取数据. 但有100个产品经理,就会有101个不同的需求. 本文以自己的vue项目为例. 2.需求描述 现有一张excel财务报表,需要根据这张excel表绘制成各种echarts图形,用于年度汇报. 不经过后端,前端独立完成. 3.功能实现 首先,为了将excel数据绘制成echarts图表,前端得拿到excel数据. 这里我们借助js-xls

  • 基于JavaScript实现数值型坐标轴刻度计算算法(echarts的y轴刻度计算)

    目录 前言 算法描述 代码 ts版本(2021/3/10补充) 结语 前言 因实习的公司是做大数据的,而我的工作刚好又是需要绘制一些数据图表的.绘制图表有许多现成的组件可以使用,但是要想达到产品所需要的效果,只靠组件内部的一些功能是不太够的.一些细腻的要求必须在掌握组件原理方法的情况下,自己去写算法来完成.例如,本文要说的这个刻度计算算法,开始正文之前,我先描述遇到的问题.echarts自身的刻度计算有时候并不好用,例如有时候你希望让图表只有5条刻度线,即分成4段,echarts提供了一个参数叫

  • 坐标轴刻度取值算法之源于echarts的y轴刻度计算需求

    目录 前言 算法描述 上代码 代码运行效果 ts版本(2021/3/10补充) 总结 前言 因实习的公司是做大数据的,而我的工作刚好又是需要绘制一些数据图表的.绘制图表有许多现成的组件可以使用,但是要想达到产品所需要的效果,只靠组件内部的一些功能是不太够的.一些细腻的要求必须在掌握组件原理方法的情况下,自己去写算法来完成.例如,本文要说的这个刻度计算算法,开始正文之前,我先描述遇到的问题. echarts自身的刻度计算有时候并不好用,例如有时候你希望让图表只有5条刻度线,即分成4段,echart

  • 实现ECharts双Y轴左右刻度线一致的例子

    不一致的情况如下图: 修改成一致的情况如下图: 代码如下: yAxis : [ { type : 'value', name : '人数', //splitLine:{show:false}, axisLabel : { formatter: '{value} 个', textStyle:{color: '#A23400'}//#A23400 purple }, axisLine:{ lineStyle:{color:'#A23400',width:'1'} //y轴坐标轴颜色 #A23400

  • ECharts设置x轴刻度间隔的2种解决方法

    目录 背景 解决方法 方法一: x轴的标签属性axisLabel下利用interval设置间隔 方法二: 为axisLabel. formatters添加回调函数改变标签文字 附:Echarts柱状图x轴间隔显示(显示不全) 总结 背景 最近在写一个echarts数据看板,要在一个页面中展示多张图表,所以留给每张图表的尺寸就很小.这也就使得图表x轴的刻度文字全部挤到一起了,废话不多说,直接上图看效果. 右边的图标就是x轴刻度标签文字被挤到一起了,左边是该过之后的效果. 解决方法 想要达到上面图片

  • javascript下数值型比较难点说明

    1.数字长长的,在c#里合法的长整型数字在javascript下竟然...... 看下面几行简单代码: 复制代码 代码如下: var a = 2010060612120909191; //按时间生成的Id1 var b = 2010060612120909199; //按时间生成的Id2 alert(a == b); //alert(a); //有什么惊人发现吗? //alert(b); //最后几位好像... //alert(Number(a) == Number(b)); //alert(p

  • 基于JavaScript代码实现随机漂浮图片广告

    在网上有很多这样的代码,不过未必符合W3C标准,因为在头部加上<!DOCTYPE html>类似标签之后,漂浮效果就会失效,下面分享一个符合标准的漂浮代码,使需要的朋友免去大量改造代码的繁琐. 代码一: 代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http:/

  • JavaScript数据类型转换实例(其他类型转字符串、数值型、布尔类型)

    前言 什么是数据类型转换? 使用表单.prompt 获取过来的数据默认类型是字符串类型的,此时就不能直接进行加减法运算,而需要转换变量的数据类型. 通俗来说,数据类型转换就是将一种数据类型转换成另外一种数据类型. 在平常代码的使用中,我们偶尔会遇到需要进行数据类型转换的时候,比如将数值型转换为字符串,或者将null/undefined转换为布尔类型等等,这篇文章我们主要讲以下三种类型的转换: 其他类型转为字符串 其他类型转为数值型 其他类型转为布尔类型 其他类型转为字符串: 有三种方法 //第一

  • 基于JavaScript实现单选框下拉菜单添加文件效果

    本节讲述单选框/下拉菜单/添加文件,综合css,html和JavaScript实现的,具体详情如下所示: 单选框: 实现的功能是:(类似平时的性格测试) 先隐藏一部分页面,然后通过点击单选框来显示. 再通过选项的选择-(每个选项有不同的积分)积分的多少来给出评语 演示代码: <html> <head> <title>DHTML技术演示---radio的使用</title> <meta http-equiv="content-Type"

  • 基于javascript的COOkie的操作实现只能点一次

    我知道很多人在网站开发的时候其实需要这个功能的,就是控制用户一直点顶什么的!所以我在这里简单写一下,基于javascript的COOkie的操作! 复制代码 代码如下: //设置cookie function setCookie(key, value) {         document.cookie = key + "=" + escape(value); } //获取cookie的值     function getCookie(key) {         if (docume

  • 基于javascript实现按圆形排列DIV元素(三)

    $(this).css({"left":Math.sin((ahd*index+ainhd))*radius+dotLeft,"top":Math.cos((ahd*index+ainhd))*radius+dotTop}); 效果图: 分析图: 上图中: 黑色:是外层容器; 黄色:是需要按椭圆运动的图片 橙色:每个图片元素距离容器顶部的距离 紫色:长半径或短半径; 蓝色:图片距离容器顶部最大的距离 绿色:坐标轴; 白色:椭圆运动轨迹; 一.原理分析: 1.1按椭圆

随机推荐