1 | import { head, indexOf, size, last } from '@antv/util';
|
2 | export var DEFAULT_Q = [1, 5, 2, 2.5, 4, 3];
|
3 | export var ALL_Q = [1, 5, 2, 2.5, 4, 3, 1.5, 7, 6, 8, 9];
|
4 | var eps = Number.EPSILON * 100;
|
5 | function mod(n, m) {
|
6 | return ((n % m) + m) % m;
|
7 | }
|
8 | function simplicity(q, Q, j, lmin, lmax, lstep) {
|
9 | var n = size(Q);
|
10 | var i = indexOf(Q, q);
|
11 | var v = 0;
|
12 | var m = mod(lmin, lstep);
|
13 | if ((m < eps || lstep - m < eps) && lmin <= 0 && lmax >= 0) {
|
14 | v = 1;
|
15 | }
|
16 | return 1 - i / (n - 1) - j + v;
|
17 | }
|
18 | function simplicityMax(q, Q, j) {
|
19 | var n = size(Q);
|
20 | var i = indexOf(Q, q);
|
21 | var v = 1;
|
22 | return 1 - i / (n - 1) - j + v;
|
23 | }
|
24 | function density(k, m, dMin, dMax, lMin, lMax) {
|
25 | var r = (k - 1) / (lMax - lMin);
|
26 | var rt = (m - 1) / (Math.max(lMax, dMax) - Math.min(dMin, lMin));
|
27 | return 2 - Math.max(r / rt, rt / r);
|
28 | }
|
29 | function densityMax(k, m) {
|
30 | if (k >= m) {
|
31 | return 2 - (k - 1) / (m - 1);
|
32 | }
|
33 | return 1;
|
34 | }
|
35 | function coverage(dMin, dMax, lMin, lMax) {
|
36 | var range = dMax - dMin;
|
37 | return 1 - (0.5 * (Math.pow((dMax - lMax), 2) + Math.pow((dMin - lMin), 2))) / Math.pow((0.1 * range), 2);
|
38 | }
|
39 | function coverageMax(dMin, dMax, span) {
|
40 | var range = dMax - dMin;
|
41 | if (span > range) {
|
42 | var half = (span - range) / 2;
|
43 | return 1 - Math.pow(half, 2) / Math.pow((0.1 * range), 2);
|
44 | }
|
45 | return 1;
|
46 | }
|
47 | function legibility() {
|
48 | return 1;
|
49 | }
|
50 |
|
51 | function prettyNumber(n) {
|
52 | return n < 1e-15 ? n : parseFloat(n.toFixed(15));
|
53 | }
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 | export default function extended(dMin, dMax, m, onlyLoose, Q, w) {
|
65 | if (m === void 0) { m = 5; }
|
66 | if (onlyLoose === void 0) { onlyLoose = true; }
|
67 | if (Q === void 0) { Q = DEFAULT_Q; }
|
68 | if (w === void 0) { w = [0.25, 0.2, 0.5, 0.05]; }
|
69 |
|
70 | if (Number.isNaN(dMin) || Number.isNaN(dMax) || typeof dMin !== 'number' || typeof dMax !== 'number' || !m) {
|
71 | return {
|
72 | min: 0,
|
73 | max: 0,
|
74 | ticks: [],
|
75 | };
|
76 | }
|
77 |
|
78 | if (dMax - dMin < 1e-15 || m === 1) {
|
79 | return {
|
80 | min: dMin,
|
81 | max: dMax,
|
82 | ticks: [dMin],
|
83 | };
|
84 | }
|
85 | var best = {
|
86 | score: -2,
|
87 | lmin: 0,
|
88 | lmax: 0,
|
89 | lstep: 0,
|
90 | };
|
91 | var j = 1;
|
92 | while (j < Infinity) {
|
93 | for (var i = 0; i < Q.length; i += 1) {
|
94 | var q = Q[i];
|
95 | var sm = simplicityMax(q, Q, j);
|
96 | if (w[0] * sm + w[1] + w[2] + w[3] < best.score) {
|
97 | j = Infinity;
|
98 | break;
|
99 | }
|
100 | var k = 2;
|
101 | while (k < Infinity) {
|
102 | var dm = densityMax(k, m);
|
103 | if (w[0] * sm + w[1] + w[2] * dm + w[3] < best.score) {
|
104 | break;
|
105 | }
|
106 | var delta = (dMax - dMin) / (k + 1) / j / q;
|
107 | var z = Math.ceil(Math.log10(delta));
|
108 | while (z < Infinity) {
|
109 | var step = j * q * Math.pow(10, z);
|
110 | var cm = coverageMax(dMin, dMax, step * (k - 1));
|
111 | if (w[0] * sm + w[1] * cm + w[2] * dm + w[3] < best.score) {
|
112 | break;
|
113 | }
|
114 | var minStart = Math.floor(dMax / step) * j - (k - 1) * j;
|
115 | var maxStart = Math.ceil(dMin / step) * j;
|
116 | if (minStart <= maxStart) {
|
117 | var count = maxStart - minStart;
|
118 | for (var i_1 = 0; i_1 <= count; i_1 += 1) {
|
119 | var start = minStart + i_1;
|
120 | var lMin = start * (step / j);
|
121 | var lMax = lMin + step * (k - 1);
|
122 | var lStep = step;
|
123 | var s = simplicity(q, Q, j, lMin, lMax, lStep);
|
124 | var c = coverage(dMin, dMax, lMin, lMax);
|
125 | var g = density(k, m, dMin, dMax, lMin, lMax);
|
126 | var l = legibility();
|
127 | var score = w[0] * s + w[1] * c + w[2] * g + w[3] * l;
|
128 | if (score > best.score && (!onlyLoose || (lMin <= dMin && lMax >= dMax))) {
|
129 | best.lmin = lMin;
|
130 | best.lmax = lMax;
|
131 | best.lstep = lStep;
|
132 | best.score = score;
|
133 | }
|
134 | }
|
135 | }
|
136 | z += 1;
|
137 | }
|
138 | k += 1;
|
139 | }
|
140 | }
|
141 | j += 1;
|
142 | }
|
143 | var lmax = best.lmax, lmin = best.lmin, lstep = best.lstep;
|
144 | var tickCount = Math.floor((lmax - lmin) / lstep) + 1;
|
145 | var ticks = new Array(tickCount);
|
146 | for (var i = 0; i < tickCount; i++) {
|
147 | ticks[i] = prettyNumber(lmin + i * lstep);
|
148 | }
|
149 | return {
|
150 | min: Math.min(dMin, head(ticks)),
|
151 | max: Math.max(dMax, last(ticks)),
|
152 | ticks: ticks,
|
153 | };
|
154 | }
|
155 |
|
\ | No newline at end of file |