一个朋友 js图表开发问题 用 c和 js 解决
引言
不求知道一切, 只求发现一件
-- 乔治·西蒙·欧姆
附注:那些存在于梦幻中的事迹,那些儿时梦中的人物,每每看起,都觉得 .哎 .... 岁月 ... 一直在努力 ... 哎 ......
愿有 同感受的经历的人 , 今天过的更舒适.
题外话
一个朋友有一次,前不久给我发了一封邮件 介绍 他在写一个js图表插件的自适应代码. 希望我能帮他从 中 找出自适应的数学规律.
他给我的信息 如下:
内容 :
这就是一道数学题,其实我还是觉得挺好玩的,就是老虎吃刺猬,不知道从哪下嘴。
附件 : 自适应max值的情况.txt,内容如下
var num = 12345 // >100,柱顶数值,我暂且写了12345
var dotnum = null;//有效数字,恒输入null进行自适应计算 function FitMKDMax(num,dotnum) {
//debugger;
var numMax = Math.round(num*X1); //Math.round 是取整,不保留小数,以下取字符串长度时小数会扰乱计算 X1为第一个想要让你求的值(我目前使用的1.3,这个值肯定在1.25~1.5之间)
var numlength = numMax.toString().length; //最大值字符串长度
if(dotnum == null){ //自适应计算有效数字位数
dotnum = 1 + numlength - Math.round(numMax * X2 / 10).toString().length;//X2是第二个想让你求的值,我目前使用的是3,和X1没有直接关系
}
var max = Math.round(num / Math.pow(10, numlength - dotnum)) * Math.pow(10, numlength - dotnum);//Math.round(a,b) 相当于求a的b次方,这里就是一个保留max有效数字位数的计算
return max;//这里返回的max还不是最终的max,最终的max要看这个max是否整除下面返回的tickInterval,不能整除时(比如max为16k,tickInterval为3k时),会向上取到一个整除值(18k)
} function FitMKDtickInterval(num) {//这里的num和上面方法的num数值相同
//debugger;
var tickInterval = Math.round(num * X2 / 10);//同样与以上的X2相同
tickInterval = Math.round(tickInterval / Math.pow(10, tickInterval.toString().length - 1)) * Math.pow(10, tickInterval.toString().length - 1);//求1位有效数字的四舍五入的计算
return tickInterval; } 求X1和X2可以满足num无论是什么数值(100以下过小的数值不算)的情况下,都能保证num这个最高的柱顶保持在y轴max位置向下移动1.5~0.75个单位长度的位置上 其中还有一个小要求,就是2.5<X2<3.33,因为是柱形图嘛,如果y轴总共只有2个单位长度不就不好看了么,这样可以保证只要有3个或4个 另外这个统计图插件叫highcharts,有时间愿意的话你可以看看,功能还是挺强的。
以上 就是 已知了.
可能看起来 不好懂,至少自己当时看的时候是不明白要干什么的.就知道这是js 代码.
写程序大家都知道,一个别人的模块 改起来比自己写要难. 别人询问你的问题都需要绕一下才能 解决.
这里 我又和 他沟通了一下 经过 自己的理解 得到 信息如下

他需要 输入一个 num 值 例如是 12345 需要 绘制一个图标,这个图标 最高点要比 num大 ,并且为了美观 不能大 1.5个单位,也不能小于 0.75单位.
可能自己说的 很不明白,直接 看代码. 权当没事,看看别人 '劣质'代码,来慰藉一下,
当时 考虑的思路 是 先 通过C写一个 函数 输入 num 输出 他要的数据. 具体的看正文
可能这篇 写的博文很水 但主要 说明两件事
1.数学 才是 最快的解决问题的工具, 还在读书的朋友们注意了
引用一句话, 学好数学,也许买菜都用不到;但 学好数学,她决定你 能在那里买菜.
2 .程序 也许总结 起来不过
输入 => 运算 => 输出
编程还是越简单越好,学了那么多,最后还是觉得面向结构编程 最简单最实用.
正文
在帮他解决问题 中 写了一段C的测试demo,看下面代码 也许上面的业务就明白.有时候,不用 说那么多,直接上代码,什么都明白了.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h> /*
* 输入 一个 num 输出 一个 x 和 y x表示 单位值, y表示 最大个数数
*
* 需要 4<=y<=6
* num + 0.75x =< xy <= num + 1.5x
*
* 推导 是 y属于 [4,6]
* num /(y-1.5) >= x >= num/(y-0.75)
*/ //测试函数
void test_xy(int num); int main(int argc, char *argv[])
{
for (int num = ; num < ; ++num)
test_xy(num); system("pause");
return ;
} static int __gethowidx(float z)
{
int d = (int)z; while (d > )
d /= ; return d;
} void
test_xy(int num)
{
float xy, xz;
int yi, zi, y;
bool flag; if (num <= )
return; printf("oldnum = %d ", num);
for (flag = true; flag; ++num) {
for (y = ; y <= ; ++y){
xy = num / (y - 1.5f);
xz = num / (y - 0.75f); yi = __gethowidx(xy);
zi = __gethowidx(xz); if (zi < yi) {
printf("num = %d => x = %d, y = %d\n", num, yi, y);
flag = false;
break;
}
}
}
}
这是 最初的设计思路, 根据简单线性规划 确定范围,后面计算.
这里 存在两个坑 就是 一个 是 test_xy 中 关于 num++ , 思路是如果找不见 换一个值找找,
但这是不合适的,例如 num = 10000,没找见,最后编程了 num = 15000找见了,这不符合要求.
这个是最初版,但是顺着这个思路 是可行的.下面 写了一个正确 的 js代码.
扯一点,当初学编程的时候,看很多人的代码都看不明白,不知道啥意思, 自己就硬着头皮敲一遍,后来就明白了.
可能编程 是 瓦匠工 + 数学做题 的一种工作,动手和动脑 都需要吧,不管从那个切入点入手,都会学的很好,前提是 你正在 写代码的路上.
后面 我用js重构的时候 , 写了一些 简单注释 , 和自己 解决问题的思路如下
<!--
问题 :
输入 一个 num 输出 一个 x 和 y. x表示 单位值, y表示 最大个数.
(x等价于你给的图中 3k, y等价于你图中的纵轴格子数) 已知 :
1. 最大格子数在 4-6之间 , 即 4 <= y <= 6 且 y是正整数
2. 并且 num距离图顶 最好在 [0.75,1.5] 单位之间 , 即 num + 0.75x <= xy <= num + 1.5x 3. 附加一个条件 为了好看 x 最好 是 100,200,...,1000,2000,3000,4000 这种类型的数 即 x % 10^[x]位数 == 0 分析 :
根据 1,2 有 num / (y - 0.75) <= x <= num / (y - 1.5)
其中 y 可取 4,5,6其中一个 这样我们可以得到 x 的三个 种类范围 y = 4 => x ∈ [num/3.75, num/2.5]
y = 5 => x ∈ [num/4.75, num/3.5]
y = 6 => x ∈ [num/5.75, num/4.5]
上面三种 取数 x y 都可以 现在根据 已知 3 , 如果 上面三个 x范围内 有 某个 值 x % 10^[x]位数 == 0 我们就取那个数 这里有个容易的算法 是 下面这样 这样 知道 这些 我们 写代码就OK了 -->
具体的实现如下,一个是 获取x值,一个获取x和y值
/*
* 根据范围 [num/3.75, num/2.5] 返回 一个合适 的 x值,如果找不见返回 0
* 只能 在 getxy函数中使用
*
* lnum int : x可取的最小值
* lnum int : y可取的最大值
* return : 0表示没有找见符合要求的数,其它就是我们要找的数
*/
function __getx(lnum, rnum) { //得到整数部分就可以了
lnum = Math.round(lnum);
rnum = Math.round(rnum); //得到二者 字符串
var lnumstr = String(lnum);
var rnumstr = String(rnum); //得到二者 第一位
var lc = lnumstr[0] - '0';
var rc = rnumstr[0] - '0'; //得到 二者长度
var ll = lnumstr.length;
var rl = rnumstr.length; // 当 后者 第一位 大于前者 第一位 那么 中间 必定包含 'rc'000 这个数 直接返回
// 或者 当 后者 比前者 长一位, 那么 也必包含 'rc'000
if (lc < rc || rl > ll)
return rc * Math.pow(10, rl - 1); //判断一下 特殊情况 假如 lnum 为 整数 那么 直接返回
if (lc * Math.pow(10, ll - 1) == lnum)
return lc * Math.pow(10, ll - 1); //没有找见
return 0;
} /*
* 属于一个 最大的num 返回 x和 y , 没有做安全检查
*
* num : 输入值 需要 > 100
* return : {
* x => 单位值大小
* y => 多少个单位值
* }
*/
function getxy(num) {
var x, y; for (y = 4; y <= 6; ++y) {
x = __getx(num / (y - 0.75), num / (y - 1.5));
if (x != 0) //找见了直接返回结果
return { "x":x, "y":y};
} // 我测试了 10000 - 40000 都没有问题 //如果没找见(找不见情况) 那么 x 设置 为 二者 中间数 例如 4100,4200,4300
y = 5;
x = num / (y - 1.5);
x = Math.round(x);
fz = Math.pow(10, String(x).length - 2);
x = x / fz * fz;
return { "x": x, "y": y };
}
到这里这个问题是水落石出了. 具体的 js测试demo如下
main.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>这里测试一段js代码</title>
<meta charset="utf-8" /> <script type="text/javascript"> //测试Demo
function test_demo(num)
{
var xy = getxy(num);
var x = xy.x,y=xy.y;
var pl = (x*y - num) / x; document.writeln("> num = " + num + " => { x = " + x + ", y = " + y + " => " + pl + "}</br>");
} //第一次测试
//test_demo(12345);
//test_demo(123456);
//test_demo(23456);
//test_demo(2000); //第二次测试
for (var i = 200; i <= 4000000; i+= Math.round(Math.random()*1000))
test_demo(i); </script>
</head>
<body> </body>
</html>
上面没写的函数 自己复制加上,再开启一个服务器,基本可以测试了.
最后今天 可能分享的有点水, 可能上面那个问题 说的不好.但是想说的意思是,勤动手,多思考,敢于挑担子帮人解决问题.
写什么样代码都不重要,重要 遇到的问题,需要去解决.方法因需要而生.
下次有机会分享工作中 如何反外挂的手段,或者解读一个云风写的字符串库,我们对它吐槽一下.反正好多.可能 写的都有点水.
让人看得蛋疼.
欢迎吐槽,共同进步.
一个朋友 js图表开发问题 用 c和 js 解决的更多相关文章
- 一个朋友js图表开发遇到的问题 解决思路c和js
引言 不求知道一切, 只求发现一件 -- 乔治·西蒙·欧姆 附注:那些存在于梦幻中的事迹,那些儿时梦中的人物,每每看起,都觉得 .哎 .... 岁月 ... 一直在努力 ... ...
- Ubuntu 14.04下搭建Node.js的开发环境
最近想找一个轻量级且支持快速开发的服务开发平台,选来选去选择了Node.js,当时有几种选择: Python + Django(用过Django,虽然开发快速,但是感觉性能并不太好). Ruby + ...
- 《Node.js入门》CentOS 6.5下Node.js Web开发环境搭建笔记
近期想尝试一下英特尔的基于WebRTC协同通信开发套件,所以须要在本地搭建Node.js Web的开发測试环境. 这里讲的是CentOS 下的搭建方法.使用Windows的小伙伴请參考: <No ...
- 求剁手的分享,如何简单开发js图表
前段时间做的一个项目里需要用到js图表,在网上找了下,大概找到了highcharts.fusioncharts这些国外产品. 因为都收费,虽然有盗版,我也不敢用,万一被找上们来就砸锅卖铁了要.自己写j ...
- 利用前端三大件(html+css+js)开发一个简单的“todolist”项目
一.介绍 todolist,即待办事项.在windows android ios上参考微软家出的那个To-Do应用,大概就是那样的.我这个更简单,功能只有“待办” “已完成”两项,并且是在浏览器打开的 ...
- 可能是史上最强大的js图表库——ECharts带你入门
PS:之前的那篇博客Highcharts——让你的网页上图表画的飞起 ,评论中,花儿笑弯了腰 和 StanZhai 两位仁兄让我试试 ECharts ,去主页看到<Why ECharts ?&g ...
- 史上最强大的js图表库——ECharts带你入门(转)
出处:http://www.cnblogs.com/zrtqsk/p/4019412.html PS:之前的那篇博客Highcharts——让你的网页上图表画的飞起 ,评论中,花儿笑弯了腰 和 Sta ...
- chart.js图表库案例赏析,饼图添加文字
chart.js图表库案例赏析,饼图添加文字 Chart.js 是一个令人印象深刻的 JavaScript 图表库,建立在 HTML5 Canvas 基础上.目前,它支持6种图表类型(折线图,条形图, ...
- 转-——推荐几个web中常用的一些js图表插件 - zccst
http://www.tuicool.com/articles/bqq2Qn 作者:zccst 我自己用过fusioncharts和highchart. jQuery插件有: TufteGraph f ...
随机推荐
- 【bzoj2073】[POI2004]PRZ 状态压缩dp
题目描述 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的人都不能超过一定的限制. 所以这只队伍过桥时只能分批 ...
- Oracle 物化视图创建以及常见问题
create materialized view MV_XXXXrefresh fast on commitwith rowidenable query rewriteasselect * from ...
- Oracle DB_LINK如何使用
语句,或可通过可视化操作 -- Create database link create database link DBL_TESTconnect to UID identified by PSWus ...
- [CF452E]Three strings
题目大意:给你三个字符串$A,B,C$,令$L=min(|A|,|B|,|C|)$,对每个$i\in[1,L]$,求出符合$A_{[a,a+i)}=B_{[b,b+i)}=C_{[c,c+i)}$的三 ...
- [bzoj] 1040 骑士 || 基环外向树dp
原题 给出n个点n条边和每个点的点权,一条边的两个断点不能同时选择,问最大可以选多少. //图是一张基环外向树森林 是不是很像舞会啊- 就是多了一条边. 所以我们考虑一下对于一棵基环外向树,拆掉一条在 ...
- 跳跃表 https://61mon.com/index.php/archives/222/
跳跃表(英文名:Skip List),于 1990 年 William Pugh 发明,是一个可以在有序元素中实现快速查询的数据结构,其插入,查找,删除操作的平均效率都为 . 跳跃表的整体性能可以和二 ...
- HDU1815 2-sat+二分
Building roads Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- ExecuteNonQuery,ExecuteReader,ExecuteScalar 区别
ExecuteNonQuery方法 :执行非查询SQL操作,包括增insert.删delete.改update ExcuteReader方法 :执行查询,返回DataReader,通过DataRead ...
- UVA 1645 Count
https://vjudge.net/problem/UVA-1645 题意:有多少个n个节点的有根树,每个深度中所有节点的子节点数相同 dp[i] 节点数为i时的答案 除去根节点还有i-1个点,如果 ...
- Linux系统查看系统信息
1. CPU # lscpu # cat /proc/cpuinfo //可以知道每个cpu信息,如每个CPU的型号,主频等 2. 内存 # free -m # cat /proc/meminfo / ...