Skip to content

Commit 71e2f7e

Browse files
committed
用不同的颜色表示危险度
1 parent 843ab86 commit 71e2f7e

File tree

1 file changed

+112
-3
lines changed

1 file changed

+112
-3
lines changed

webapi/core.js

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,115 @@
11
"use strict";
22

3+
let maj_risk = (function() {
4+
5+
// https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
6+
7+
/**
8+
* Converts an HSL color value to RGB. Conversion formula
9+
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
10+
* Assumes h, s, and l are contained in the set [0, 1] and
11+
* returns r, g, and b in the set [0, 255].
12+
*
13+
* @param {number} h The hue
14+
* @param {number} s The saturation
15+
* @param {number} l The lightness
16+
* @return {Array} The RGB representation
17+
*/
18+
function hslToRgb(h, s, l){
19+
var r, g, b;
20+
21+
if(s == 0){
22+
r = g = b = l; // achromatic
23+
}else{
24+
var hue2rgb = function hue2rgb(p, q, t){
25+
if(t < 0) t += 1;
26+
if(t > 1) t -= 1;
27+
if(t < 1/6) return p + (q - p) * 6 * t;
28+
if(t < 1/2) return q;
29+
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
30+
return p;
31+
}
32+
33+
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
34+
var p = 2 * l - q;
35+
r = hue2rgb(p, q, h + 1/3);
36+
g = hue2rgb(p, q, h);
37+
b = hue2rgb(p, q, h - 1/3);
38+
}
39+
40+
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
41+
}
42+
43+
/**
44+
* Converts an RGB color value to HSL. Conversion formula
45+
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
46+
* Assumes r, g, and b are contained in the set [0, 255] and
47+
* returns h, s, and l in the set [0, 1].
48+
*
49+
* @param {number} r The red color value
50+
* @param {number} g The green color value
51+
* @param {number} b The blue color value
52+
* @return {Array} The HSL representation
53+
*/
54+
function rgbToHsl(r, g, b){
55+
r /= 255, g /= 255, b /= 255;
56+
var max = Math.max(r, g, b), min = Math.min(r, g, b);
57+
var h, s, l = (max + min) / 2;
58+
59+
if(max == min){
60+
h = s = 0; // achromatic
61+
}else{
62+
var d = max - min;
63+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
64+
switch(max){
65+
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
66+
case g: h = (b - r) / d + 2; break;
67+
case b: h = (r - g) / d + 4; break;
68+
}
69+
h /= 6;
70+
}
71+
72+
return [h, s, l];
73+
}
74+
75+
let gradient = [
76+
{ risk: 0.0 , color: [255, 255, 255] }, // 绝安,白色
77+
{ risk: 1e-5 , color: [131, 179, 17] }, // 只要有一点风险,鸭绿色
78+
{ risk: 8 , color: [250, 195, 0] }, // 还可以冲一冲, 橙黄色
79+
{ risk: 16 , color: [253, 99, 0] }, // 相当危险,粉色
80+
{ risk: 25.0, color: [253, 0, 135] }, // 绝对危险, 红色
81+
];
82+
83+
// https://stackoverflow.com/questions/4856717/javascript-equivalent-of-pythons-zip-function
84+
let zip = rows=>rows[0].map((_,c)=>rows.map(row=>row[c]));
85+
86+
return {
87+
get_rist_color(risk) {
88+
risk = Math.min(risk, gradient[gradient.length-1].risk);
89+
90+
for (let i = 0; i + 1 < gradient.length; i++) {
91+
if (risk <= gradient[i + 1].risk) {
92+
// let left = rgbToHsl.apply(null, gradient[i].color);
93+
// let right = rgbToHsl.apply(null, gradient[i + 1].color);
94+
let left = gradient[i].color;
95+
let right = gradient[i+1].color;
96+
// interpolation in RGB color space
97+
// HSL 效果似乎并不如人意
98+
let ratio = (risk - gradient[i].risk) / (gradient[i + 1].risk - gradient[i].risk);
99+
let result = zip([left, right]).map(([x, y]) => x + (y - x) * ratio);
100+
101+
// let rgba = hslToRgb.apply(null, (result)).join(',');
102+
let rgba = result;
103+
return `rgba(${rgba})`;
104+
}
105+
}
106+
107+
throw "can not find a color for the risk " + risk;
108+
}
109+
};
110+
111+
})(); // closure for maj_risk
112+
3113
function tile_img_url(index) {
4114
function label(index) {
5115
let offset = [0, 9, 18, 27, 34];
@@ -27,14 +137,13 @@ function show_tiles(data) {
27137

28138
for (let i = 0; i < 34; i++) {
29139
var risk = data["risk"] === null ? 0 : data["risk"][i];
30-
risk = risk / 25;
31-
risk = Math.min(risk, 1.0);
140+
32141
let count = data["counts"][i];
33142
for (let c = 0; c < count; c++) {
34143
let img = document.createElement("img");
35144
img.src = tile_img_url(i);
36145
img.classList.add("tile");
37-
img.style.border = `solid 3px rgba(255, 0, 0, ${risk})`;
146+
img.style.border = `solid 3px ${maj_risk.get_rist_color(risk)}`;
38147
container.appendChild(img);
39148
}
40149
}

0 commit comments

Comments
 (0)