@easyv/charts 1.9.17 → 1.9.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/Axis.js +153 -12
- package/lib/hooks/useExtentData.js +1 -1
- package/package.json +1 -1
- package/src/components/Axis.tsx +207 -22
- package/src/components/Label.js +10 -3
- package/src/hooks/useExtentData.js +1 -4
package/lib/components/Axis.js
CHANGED
|
@@ -5,10 +5,11 @@ var _typeof3 = require("@babel/runtime/helpers/typeof");
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports["default"] = void 0;
|
|
8
|
+
exports["default"] = exports.calculateTextWidth = void 0;
|
|
9
9
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
10
|
-
var
|
|
10
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
11
11
|
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
12
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
12
13
|
var _react = _interopRequireWildcard(require("react"));
|
|
13
14
|
var _utils = require("../utils");
|
|
14
15
|
var _context = require("../context");
|
|
@@ -20,6 +21,43 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
|
|
|
20
21
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /**
|
|
21
22
|
* x, y, z轴
|
|
22
23
|
*/
|
|
24
|
+
var canvasContext = null;
|
|
25
|
+
var getCanvasContext = function getCanvasContext() {
|
|
26
|
+
if (!canvasContext) {
|
|
27
|
+
// 创建离线Canvas(不挂载到DOM,仅用于计算)
|
|
28
|
+
var canvas = document.createElement("canvas");
|
|
29
|
+
canvasContext = canvas.getContext("2d");
|
|
30
|
+
if (!canvasContext) {
|
|
31
|
+
throw new Error("浏览器不支持Canvas");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return canvasContext;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
//计算文本宽度的函数
|
|
38
|
+
var calculateTextWidth = exports.calculateTextWidth = function calculateTextWidth(text, fontConfig) {
|
|
39
|
+
if (!text) return 0;
|
|
40
|
+
var ctx = getCanvasContext();
|
|
41
|
+
ctx.save();
|
|
42
|
+
var fontStyle = fontConfig.italic ? "italic" : "normal";
|
|
43
|
+
var fontWeight = fontConfig.bold ? "bold" : "normal";
|
|
44
|
+
var fontSize = typeof fontConfig.fontSize === "number" ? "".concat(fontConfig.fontSize, "px") : fontConfig.fontSize || "12px";
|
|
45
|
+
var fontFamily = fontConfig.fontFamily || "Microsoft Yahei";
|
|
46
|
+
var letterSpacing = Number(fontConfig.letterSpacing) || 0;
|
|
47
|
+
var letterSpacingWithUnit = "".concat(letterSpacing, "px");
|
|
48
|
+
ctx.font = "".concat(fontWeight, " ").concat(fontStyle, " ").concat(fontSize, " ").concat(fontFamily);
|
|
49
|
+
ctx.letterSpacing = letterSpacingWithUnit;
|
|
50
|
+
var totalWidth;
|
|
51
|
+
if (typeof ctx.letterSpacing !== "undefined") {
|
|
52
|
+
totalWidth = ctx.measureText(text).width;
|
|
53
|
+
} else {
|
|
54
|
+
var baseWidth = ctx.measureText(text).width;
|
|
55
|
+
var spacingWidth = text.length * letterSpacing;
|
|
56
|
+
totalWidth = baseWidth + spacingWidth;
|
|
57
|
+
}
|
|
58
|
+
ctx.restore();
|
|
59
|
+
return totalWidth;
|
|
60
|
+
};
|
|
23
61
|
var defaultEvent = function defaultEvent() {};
|
|
24
62
|
var defaultAppearance = {
|
|
25
63
|
angle: 0,
|
|
@@ -152,6 +190,23 @@ var Unit = function Unit(_ref4) {
|
|
|
152
190
|
textAnchor: textAnchor
|
|
153
191
|
}, dataUnit || text);
|
|
154
192
|
};
|
|
193
|
+
function maxLabelFT(data, config, formatter, font) {
|
|
194
|
+
var max = 0;
|
|
195
|
+
data.length ? data.forEach(function (item) {
|
|
196
|
+
if (calculateTextWidth(formatter(item, _objectSpread(_objectSpread({}, config), {}, {
|
|
197
|
+
format: {
|
|
198
|
+
type: config.format,
|
|
199
|
+
showType: config.showType
|
|
200
|
+
}
|
|
201
|
+
})), font) > max) max = calculateTextWidth(formatter(item, _objectSpread(_objectSpread({}, config), {}, {
|
|
202
|
+
format: {
|
|
203
|
+
type: config.format,
|
|
204
|
+
showType: config.showType
|
|
205
|
+
}
|
|
206
|
+
})), font);
|
|
207
|
+
}) : "";
|
|
208
|
+
return max;
|
|
209
|
+
}
|
|
155
210
|
var Label = function Label(_ref5) {
|
|
156
211
|
var className = _ref5.className,
|
|
157
212
|
_ref5$orientation = _ref5.orientation,
|
|
@@ -172,6 +227,7 @@ var Label = function Label(_ref5) {
|
|
|
172
227
|
events = _ref5$events === void 0 ? defaultEvent : _ref5$events,
|
|
173
228
|
_ref5$config = _ref5.config,
|
|
174
229
|
show = _ref5$config.show,
|
|
230
|
+
labelNum = _ref5$config.labelNum,
|
|
175
231
|
style = _ref5$config.style,
|
|
176
232
|
_ref5$config$translat = _ref5$config.translate,
|
|
177
233
|
translateX = _ref5$config$translat.x,
|
|
@@ -183,9 +239,15 @@ var Label = function Label(_ref5) {
|
|
|
183
239
|
_ref5$config$appearan2 = _ref5$config$appearan === void 0 ? defaultAppearance : _ref5$config$appearan,
|
|
184
240
|
width = _ref5$config$appearan2.width,
|
|
185
241
|
speed = _ref5$config$appearan2.speed,
|
|
186
|
-
textOverflow = _ref5$config$appearan2.textOverflow
|
|
242
|
+
textOverflow = _ref5$config$appearan2.textOverflow,
|
|
243
|
+
LabelWidth = _ref5.LabelWidth;
|
|
187
244
|
if (!show) return null;
|
|
188
|
-
var _label = formatter(label, config)
|
|
245
|
+
var _label = formatter(label, _objectSpread(_objectSpread({}, config), {}, {
|
|
246
|
+
format: {
|
|
247
|
+
type: config.format,
|
|
248
|
+
showType: config.showType
|
|
249
|
+
}
|
|
250
|
+
}));
|
|
189
251
|
var _getLayout = getLayout(orientation, rotate),
|
|
190
252
|
transform = _getLayout.transform,
|
|
191
253
|
directionX = _getLayout.directionX,
|
|
@@ -194,6 +256,7 @@ var Label = function Label(_ref5) {
|
|
|
194
256
|
var x = (isVertical ? tickSize * directionX : coordinate) + translateX * directionX;
|
|
195
257
|
var y = (isVertical ? coordinate : tickSize * directionY) + translateY * directionY;
|
|
196
258
|
var _style = style && ((0, _typeof2["default"])(style) == "object" ? style : style(_label));
|
|
259
|
+
//x轴显示
|
|
197
260
|
return /*#__PURE__*/_react["default"].createElement("foreignObject", {
|
|
198
261
|
width: "100%",
|
|
199
262
|
height: "100%"
|
|
@@ -217,7 +280,7 @@ var Label = function Label(_ref5) {
|
|
|
217
280
|
cursor: "pointer",
|
|
218
281
|
transform: "translate(".concat(x + (isIOS ? iosX : 0), "px, ").concat(y + (isIOS ? iosY : 0), "px)") // 用 transform 定位
|
|
219
282
|
})
|
|
220
|
-
}, /*#__PURE__*/_react["default"].createElement(_TextOverflow["default"], {
|
|
283
|
+
}, labelNum == "Fixed" ? /*#__PURE__*/_react["default"].createElement(_TextOverflow["default"], {
|
|
221
284
|
ShowType: "normal",
|
|
222
285
|
type: textOverflow,
|
|
223
286
|
speed: speed,
|
|
@@ -228,17 +291,28 @@ var Label = function Label(_ref5) {
|
|
|
228
291
|
textAlign: textAlign,
|
|
229
292
|
justifyContent: textAlign == "left" ? "flex-start" : textAlign == "right" ? "flex-end" : "center"
|
|
230
293
|
}
|
|
231
|
-
})
|
|
294
|
+
}) : /*#__PURE__*/_react["default"].createElement("span", {
|
|
295
|
+
style: {
|
|
296
|
+
width: LabelWidth,
|
|
297
|
+
transform: transform,
|
|
298
|
+
justifyContent: "flex-start",
|
|
299
|
+
display: "block",
|
|
300
|
+
top: translateY,
|
|
301
|
+
left: translateX
|
|
302
|
+
}
|
|
303
|
+
}, _label)));
|
|
232
304
|
};
|
|
233
305
|
var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(/*#__PURE__*/(0, _react.forwardRef)(function (_ref6, ref) {
|
|
234
|
-
var
|
|
306
|
+
var allTicks = _ref6.allTicks,
|
|
307
|
+
orientation = _ref6.orientation,
|
|
235
308
|
scaler = _ref6.scaler,
|
|
236
309
|
_ref6$tickSize = _ref6.tickSize,
|
|
237
310
|
tickSize = _ref6$tickSize === void 0 ? defaultTickSize : _ref6$tickSize,
|
|
238
|
-
|
|
311
|
+
tickss = _ref6.ticks,
|
|
239
312
|
formatter = _ref6.formatter,
|
|
240
313
|
rotate = _ref6.rotate,
|
|
241
314
|
triggerEvents = _ref6.triggerEvents,
|
|
315
|
+
config = _ref6.config,
|
|
242
316
|
_ref6$config = _ref6.config,
|
|
243
317
|
on = _ref6$config.on,
|
|
244
318
|
label = _ref6$config.label,
|
|
@@ -259,8 +333,8 @@ var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(/*#__PURE__*/(
|
|
|
259
333
|
yLineRange = _ref6.yLineRange,
|
|
260
334
|
clipAxisRange = _ref6.clipAxisRange,
|
|
261
335
|
controlInfo = _ref6.controlInfo,
|
|
262
|
-
rawTicks = _ref6.rawTicks
|
|
263
|
-
|
|
336
|
+
rawTicks = _ref6.rawTicks,
|
|
337
|
+
paddingOuter = _ref6.paddingOuter;
|
|
264
338
|
var _useContext = (0, _react.useContext)(_context.chartContext),
|
|
265
339
|
width = _useContext.width,
|
|
266
340
|
height = _useContext.height,
|
|
@@ -270,6 +344,71 @@ var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(/*#__PURE__*/(
|
|
|
270
344
|
cPercent = controlInfo.cPercent;
|
|
271
345
|
var x = orientation == "right" ? width : 0;
|
|
272
346
|
var y = orientation == "bottom" ? height - cHeight : 0;
|
|
347
|
+
var LabelWidth = 1;
|
|
348
|
+
if (label.labelNum == "Fixed") {
|
|
349
|
+
LabelWidth = label.appearance.width;
|
|
350
|
+
} else {
|
|
351
|
+
if (allTicks.length && typeof allTicks[0] == "string") {
|
|
352
|
+
LabelWidth = maxLabelFT(allTicks, label, formatter, label.font);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
var LabelNum = Math.floor(width / (isC ? cPercent : 1) * (1 - paddingOuter) / LabelWidth);
|
|
356
|
+
var ticks = label.labelNum == "Fixed" ? tickss : getEvenlySpacedElements(allTicks, LabelNum < allTicks.length ? LabelNum > allTicks.length / 2 ? Math.ceil(allTicks.length / 2) : LabelNum : allTicks.length, label.showLast);
|
|
357
|
+
if (!(on && ticks.length > 0)) return null;
|
|
358
|
+
|
|
359
|
+
//数据抽取逻辑
|
|
360
|
+
function getEvenlySpacedElements(arr, expectCount) {
|
|
361
|
+
var acc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
362
|
+
if (!arr.length || expectCount <= 0) return [];
|
|
363
|
+
if (expectCount >= arr.length) return (0, _toConsumableArray2["default"])(arr);
|
|
364
|
+
if (expectCount === 1) return [arr[0]];
|
|
365
|
+
if (acc) {
|
|
366
|
+
var totalLength = arr.length;
|
|
367
|
+
var result = [];
|
|
368
|
+
var bestCount = 2;
|
|
369
|
+
for (var k = expectCount; k >= 2; k--) {
|
|
370
|
+
var denominator = k - 1;
|
|
371
|
+
var numerator = totalLength - 1;
|
|
372
|
+
if (denominator > 0 && numerator % denominator === 0) {
|
|
373
|
+
bestCount = k;
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
var step = (totalLength - 1) / (bestCount - 1);
|
|
378
|
+
for (var i = 0; i < bestCount; i++) {
|
|
379
|
+
var rawIndex = i * step;
|
|
380
|
+
var index = Math.ceil(rawIndex);
|
|
381
|
+
var safeIndex = Math.max(0, Math.min(totalLength - 1, index));
|
|
382
|
+
result.push(arr[safeIndex]);
|
|
383
|
+
}
|
|
384
|
+
if (result.length > 0) result[0] = arr[0];
|
|
385
|
+
if (result.length >= 2) result[result.length - 1] = arr[totalLength - 1];
|
|
386
|
+
return result;
|
|
387
|
+
} else {
|
|
388
|
+
// 重构acc=false逻辑:优先均匀分布,不强制首尾
|
|
389
|
+
var _result = [];
|
|
390
|
+
var arrLen = arr.length;
|
|
391
|
+
if (expectCount === 2) {
|
|
392
|
+
_result.push(arr[0]);
|
|
393
|
+
_result.push(arr[arrLen - 1]);
|
|
394
|
+
return _result;
|
|
395
|
+
}
|
|
396
|
+
var idealStep = (arrLen - 1) / (expectCount - 1);
|
|
397
|
+
var isIdealStepInteger = Math.abs(idealStep - Math.round(idealStep)) < 1e-10;
|
|
398
|
+
if (isIdealStepInteger) {
|
|
399
|
+
for (var _i = 0; _i < expectCount; _i++) {
|
|
400
|
+
var _index = _i * idealStep;
|
|
401
|
+
_result.push(arr[_index]);
|
|
402
|
+
}
|
|
403
|
+
} else {
|
|
404
|
+
var _step = Math.max(1, Math.floor(arrLen / expectCount));
|
|
405
|
+
for (var _i2 = 0; _i2 < arrLen && _result.length < expectCount; _i2 += _step) {
|
|
406
|
+
_result.push(arr[_i2]);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return _result;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
273
412
|
function drawAxisTickLine() {
|
|
274
413
|
var draw = function draw(ticks, scaler) {
|
|
275
414
|
return ticks.map(function (tick, index) {
|
|
@@ -333,7 +472,8 @@ var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(/*#__PURE__*/(
|
|
|
333
472
|
tickSize: _tickSize,
|
|
334
473
|
formatter: formatter,
|
|
335
474
|
rotate: rotate,
|
|
336
|
-
events: triggerEvents
|
|
475
|
+
events: triggerEvents,
|
|
476
|
+
LabelWidth: LabelWidth
|
|
337
477
|
}), gridLine && /*#__PURE__*/_react["default"].createElement(_element.Line, (0, _extends2["default"])({
|
|
338
478
|
className: "__easyv-gridLine",
|
|
339
479
|
config: gridLine
|
|
@@ -345,7 +485,8 @@ var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(/*#__PURE__*/(
|
|
|
345
485
|
return draw(ticks, scaler[index]);
|
|
346
486
|
}));
|
|
347
487
|
} else if (isC && orientation == "bottom") {
|
|
348
|
-
return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, draw(
|
|
488
|
+
return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, draw(ticks, scaler));
|
|
489
|
+
// return <>{draw(rawTicks, scaler)}</>;
|
|
349
490
|
} else {
|
|
350
491
|
return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, draw(ticks, scaler));
|
|
351
492
|
}
|
|
@@ -91,7 +91,7 @@ var _default = exports["default"] = function _default(_ref) {
|
|
|
91
91
|
if (xAxis) {
|
|
92
92
|
var _xAxis$config$label = xAxis.config.label,
|
|
93
93
|
autoSort = _xAxis$config$label.autoSort,
|
|
94
|
-
type = _xAxis$config$label.format
|
|
94
|
+
type = _xAxis$config$label.format;
|
|
95
95
|
if (type == "date" && autoSort) {
|
|
96
96
|
x.sort(function (a, b) {
|
|
97
97
|
return new Date(a).getTime() - new Date(b).getTime();
|
package/package.json
CHANGED
package/src/components/Axis.tsx
CHANGED
|
@@ -15,6 +15,47 @@ import { chartContext } from "../context";
|
|
|
15
15
|
import { Line } from "../element";
|
|
16
16
|
import TextOverflow from "./TextOverflow";
|
|
17
17
|
import { path } from "d3";
|
|
18
|
+
let canvasContext: CanvasRenderingContext2D | null = null;
|
|
19
|
+
const getCanvasContext = (): CanvasRenderingContext2D => {
|
|
20
|
+
if (!canvasContext) {
|
|
21
|
+
// 创建离线Canvas(不挂载到DOM,仅用于计算)
|
|
22
|
+
const canvas = document.createElement("canvas");
|
|
23
|
+
canvasContext = canvas.getContext("2d");
|
|
24
|
+
if (!canvasContext) {
|
|
25
|
+
throw new Error("浏览器不支持Canvas");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return canvasContext;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
//计算文本宽度的函数
|
|
32
|
+
export const calculateTextWidth = (text: string, fontConfig: any): number => {
|
|
33
|
+
if (!text) return 0;
|
|
34
|
+
const ctx = getCanvasContext();
|
|
35
|
+
ctx.save();
|
|
36
|
+
|
|
37
|
+
const fontStyle = fontConfig.italic ? "italic" : "normal";
|
|
38
|
+
const fontWeight = fontConfig.bold ? "bold" : "normal";
|
|
39
|
+
const fontSize =
|
|
40
|
+
typeof fontConfig.fontSize === "number"
|
|
41
|
+
? `${fontConfig.fontSize}px`
|
|
42
|
+
: fontConfig.fontSize || "12px";
|
|
43
|
+
const fontFamily = fontConfig.fontFamily || "Microsoft Yahei";
|
|
44
|
+
const letterSpacing = Number(fontConfig.letterSpacing) || 0;
|
|
45
|
+
const letterSpacingWithUnit = `${letterSpacing}px`;
|
|
46
|
+
ctx.font = `${fontWeight} ${fontStyle} ${fontSize} ${fontFamily}`;
|
|
47
|
+
ctx.letterSpacing = letterSpacingWithUnit;
|
|
48
|
+
let totalWidth;
|
|
49
|
+
if (typeof ctx.letterSpacing !== "undefined") {
|
|
50
|
+
totalWidth = ctx.measureText(text).width;
|
|
51
|
+
} else {
|
|
52
|
+
const baseWidth = ctx.measureText(text).width;
|
|
53
|
+
const spacingWidth = text.length * letterSpacing;
|
|
54
|
+
totalWidth = baseWidth + spacingWidth;
|
|
55
|
+
}
|
|
56
|
+
ctx.restore();
|
|
57
|
+
return totalWidth;
|
|
58
|
+
};
|
|
18
59
|
const defaultEvent = () => {};
|
|
19
60
|
const defaultAppearance = {
|
|
20
61
|
angle: 0,
|
|
@@ -185,14 +226,42 @@ type LabelType = {
|
|
|
185
226
|
events?: Function;
|
|
186
227
|
config: {
|
|
187
228
|
show: boolean;
|
|
229
|
+
labelNum: string;
|
|
188
230
|
translate: Translate;
|
|
189
231
|
font: Font;
|
|
190
232
|
textAlign: TextAlign;
|
|
191
233
|
style: CSSProperties | Function;
|
|
192
234
|
appearance?: appearance;
|
|
235
|
+
format: string;
|
|
236
|
+
showType: string;
|
|
193
237
|
};
|
|
238
|
+
LabelWidth: any;
|
|
194
239
|
};
|
|
195
240
|
|
|
241
|
+
function maxLabelFT(data: any, config: any, formatter: any, font: any) {
|
|
242
|
+
let max = 0;
|
|
243
|
+
data.length
|
|
244
|
+
? data.forEach((item: any) => {
|
|
245
|
+
if (
|
|
246
|
+
calculateTextWidth(
|
|
247
|
+
formatter(item, {
|
|
248
|
+
...config,
|
|
249
|
+
format: { type: config.format, showType: config.showType },
|
|
250
|
+
}),
|
|
251
|
+
font
|
|
252
|
+
) > max
|
|
253
|
+
)
|
|
254
|
+
max = calculateTextWidth(
|
|
255
|
+
formatter(item, {
|
|
256
|
+
...config,
|
|
257
|
+
format: { type: config.format, showType: config.showType },
|
|
258
|
+
}),
|
|
259
|
+
font
|
|
260
|
+
);
|
|
261
|
+
})
|
|
262
|
+
: "";
|
|
263
|
+
return max;
|
|
264
|
+
}
|
|
196
265
|
const Label: (
|
|
197
266
|
props: LabelType
|
|
198
267
|
) => ReactComponentElement<ComponentType> | null = ({
|
|
@@ -208,15 +277,20 @@ const Label: (
|
|
|
208
277
|
events = defaultEvent,
|
|
209
278
|
config: {
|
|
210
279
|
show,
|
|
280
|
+
labelNum,
|
|
211
281
|
style,
|
|
212
282
|
translate: { x: translateX, y: translateY },
|
|
213
283
|
font,
|
|
214
284
|
textAlign = "center",
|
|
215
285
|
appearance: { width, speed, textOverflow } = defaultAppearance,
|
|
216
286
|
},
|
|
287
|
+
LabelWidth,
|
|
217
288
|
}) => {
|
|
218
289
|
if (!show) return null;
|
|
219
|
-
const _label = formatter(label,
|
|
290
|
+
const _label = formatter(label, {
|
|
291
|
+
...config,
|
|
292
|
+
format: { type: config.format, showType: config.showType },
|
|
293
|
+
});
|
|
220
294
|
const { transform, directionX, directionY } = getLayout(orientation, rotate);
|
|
221
295
|
const isVertical = orientation == "left" || orientation == "right";
|
|
222
296
|
|
|
@@ -226,7 +300,7 @@ const Label: (
|
|
|
226
300
|
(isVertical ? coordinate : tickSize * directionY) + translateY * directionY;
|
|
227
301
|
|
|
228
302
|
const _style = style && (typeof style == "object" ? style : style(_label));
|
|
229
|
-
|
|
303
|
+
//x轴显示
|
|
230
304
|
return (
|
|
231
305
|
<foreignObject
|
|
232
306
|
width="100%"
|
|
@@ -249,23 +323,38 @@ const Label: (
|
|
|
249
323
|
}px)`, // 用 transform 定位
|
|
250
324
|
}}
|
|
251
325
|
>
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
326
|
+
{labelNum == "Fixed" ? (
|
|
327
|
+
<TextOverflow
|
|
328
|
+
ShowType="normal"
|
|
329
|
+
type={textOverflow}
|
|
330
|
+
speed={speed}
|
|
331
|
+
value={_label}
|
|
332
|
+
style={{
|
|
333
|
+
width,
|
|
334
|
+
transform,
|
|
335
|
+
textAlign,
|
|
336
|
+
justifyContent:
|
|
337
|
+
textAlign == "left"
|
|
338
|
+
? "flex-start"
|
|
339
|
+
: textAlign == "right"
|
|
340
|
+
? "flex-end"
|
|
341
|
+
: "center",
|
|
342
|
+
}}
|
|
343
|
+
></TextOverflow>
|
|
344
|
+
) : (
|
|
345
|
+
<span
|
|
346
|
+
style={{
|
|
347
|
+
width: LabelWidth,
|
|
348
|
+
transform,
|
|
349
|
+
justifyContent: "flex-start",
|
|
350
|
+
display: "block",
|
|
351
|
+
top: translateY,
|
|
352
|
+
left: translateX,
|
|
353
|
+
}}
|
|
354
|
+
>
|
|
355
|
+
{_label}
|
|
356
|
+
</span>
|
|
357
|
+
)}
|
|
269
358
|
</div>
|
|
270
359
|
</foreignObject>
|
|
271
360
|
);
|
|
@@ -275,13 +364,15 @@ export default memo(
|
|
|
275
364
|
forwardRef(
|
|
276
365
|
(
|
|
277
366
|
{
|
|
367
|
+
allTicks,
|
|
278
368
|
orientation,
|
|
279
369
|
scaler,
|
|
280
370
|
tickSize = defaultTickSize,
|
|
281
|
-
ticks,
|
|
371
|
+
ticks: tickss,
|
|
282
372
|
formatter,
|
|
283
373
|
rotate,
|
|
284
374
|
triggerEvents,
|
|
375
|
+
config,
|
|
285
376
|
config: { on, label, axisLine, tickLine, gridLine, unit },
|
|
286
377
|
margin: { marginLeft, marginTop },
|
|
287
378
|
positions,
|
|
@@ -296,15 +387,107 @@ export default memo(
|
|
|
296
387
|
//控制图相关
|
|
297
388
|
controlInfo,
|
|
298
389
|
rawTicks,
|
|
390
|
+
paddingOuter,
|
|
299
391
|
}: any,
|
|
300
392
|
ref
|
|
301
393
|
) => {
|
|
302
|
-
if (!(on && ticks.length > 0)) return null;
|
|
303
394
|
const { width, height, isIOS } = useContext(chartContext);
|
|
304
395
|
const { cHeight, isC, cPercent } = controlInfo;
|
|
305
396
|
const x = orientation == "right" ? width : 0;
|
|
306
397
|
const y = orientation == "bottom" ? height - cHeight : 0;
|
|
398
|
+
let LabelWidth = 1;
|
|
399
|
+
if (label.labelNum == "Fixed") {
|
|
400
|
+
LabelWidth = label.appearance.width;
|
|
401
|
+
} else {
|
|
402
|
+
if (allTicks.length && typeof allTicks[0] == "string") {
|
|
403
|
+
LabelWidth = maxLabelFT(allTicks, label, formatter, label.font);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
const LabelNum = Math.floor(
|
|
407
|
+
((width / (isC ? cPercent : 1)) * (1 - paddingOuter)) / LabelWidth
|
|
408
|
+
);
|
|
409
|
+
const ticks: any =
|
|
410
|
+
label.labelNum == "Fixed"
|
|
411
|
+
? tickss
|
|
412
|
+
: getEvenlySpacedElements(
|
|
413
|
+
allTicks,
|
|
414
|
+
LabelNum < allTicks.length
|
|
415
|
+
? LabelNum > allTicks.length / 2
|
|
416
|
+
? Math.ceil(allTicks.length / 2)
|
|
417
|
+
: LabelNum
|
|
418
|
+
: allTicks.length,
|
|
419
|
+
label.showLast
|
|
420
|
+
);
|
|
421
|
+
if (!(on && ticks.length > 0)) return null;
|
|
422
|
+
|
|
423
|
+
//数据抽取逻辑
|
|
424
|
+
function getEvenlySpacedElements(
|
|
425
|
+
arr: any[],
|
|
426
|
+
expectCount: number,
|
|
427
|
+
acc: boolean = false
|
|
428
|
+
): any[] {
|
|
429
|
+
if (!arr.length || expectCount <= 0) return [];
|
|
430
|
+
if (expectCount >= arr.length) return [...arr];
|
|
431
|
+
if (expectCount === 1) return [arr[0]];
|
|
432
|
+
|
|
433
|
+
if (acc) {
|
|
434
|
+
const totalLength = arr.length;
|
|
435
|
+
const result: any[] = [];
|
|
436
|
+
|
|
437
|
+
let bestCount = 2;
|
|
438
|
+
for (let k = expectCount; k >= 2; k--) {
|
|
439
|
+
const denominator = k - 1;
|
|
440
|
+
const numerator = totalLength - 1;
|
|
441
|
+
if (denominator > 0 && numerator % denominator === 0) {
|
|
442
|
+
bestCount = k;
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
307
446
|
|
|
447
|
+
const step = (totalLength - 1) / (bestCount - 1);
|
|
448
|
+
for (let i = 0; i < bestCount; i++) {
|
|
449
|
+
const rawIndex = i * step;
|
|
450
|
+
const index = Math.ceil(rawIndex);
|
|
451
|
+
const safeIndex = Math.max(0, Math.min(totalLength - 1, index));
|
|
452
|
+
result.push(arr[safeIndex]);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (result.length > 0) result[0] = arr[0];
|
|
456
|
+
if (result.length >= 2)
|
|
457
|
+
result[result.length - 1] = arr[totalLength - 1];
|
|
458
|
+
|
|
459
|
+
return result;
|
|
460
|
+
} else {
|
|
461
|
+
// 重构acc=false逻辑:优先均匀分布,不强制首尾
|
|
462
|
+
const result: any[] = [];
|
|
463
|
+
const arrLen = arr.length;
|
|
464
|
+
if (expectCount === 2) {
|
|
465
|
+
result.push(arr[0]);
|
|
466
|
+
result.push(arr[arrLen - 1]);
|
|
467
|
+
return result;
|
|
468
|
+
}
|
|
469
|
+
const idealStep = (arrLen - 1) / (expectCount - 1);
|
|
470
|
+
const isIdealStepInteger =
|
|
471
|
+
Math.abs(idealStep - Math.round(idealStep)) < 1e-10;
|
|
472
|
+
|
|
473
|
+
if (isIdealStepInteger) {
|
|
474
|
+
for (let i = 0; i < expectCount; i++) {
|
|
475
|
+
const index = i * idealStep;
|
|
476
|
+
result.push(arr[index]);
|
|
477
|
+
}
|
|
478
|
+
} else {
|
|
479
|
+
const step = Math.max(1, Math.floor(arrLen / expectCount));
|
|
480
|
+
for (
|
|
481
|
+
let i = 0;
|
|
482
|
+
i < arrLen && result.length < expectCount;
|
|
483
|
+
i += step
|
|
484
|
+
) {
|
|
485
|
+
result.push(arr[i]);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return result;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
308
491
|
function drawAxisTickLine() {
|
|
309
492
|
const draw = (ticks: any, scaler: any) => {
|
|
310
493
|
return ticks.map((tick: string, index: number) => {
|
|
@@ -395,6 +578,7 @@ export default memo(
|
|
|
395
578
|
formatter={formatter}
|
|
396
579
|
rotate={rotate}
|
|
397
580
|
events={triggerEvents}
|
|
581
|
+
LabelWidth={LabelWidth}
|
|
398
582
|
/>
|
|
399
583
|
)}
|
|
400
584
|
{gridLine && (
|
|
@@ -418,7 +602,8 @@ export default memo(
|
|
|
418
602
|
</>
|
|
419
603
|
);
|
|
420
604
|
} else if (isC && orientation == "bottom") {
|
|
421
|
-
return <>{draw(
|
|
605
|
+
return <>{draw(ticks, scaler)}</>;
|
|
606
|
+
// return <>{draw(rawTicks, scaler)}</>;
|
|
422
607
|
} else {
|
|
423
608
|
return <>{draw(ticks, scaler)}</>;
|
|
424
609
|
}
|
package/src/components/Label.js
CHANGED
|
@@ -45,10 +45,16 @@ export default memo(
|
|
|
45
45
|
selectStyle,
|
|
46
46
|
bandLength = 0,
|
|
47
47
|
data,
|
|
48
|
-
xAxis: {
|
|
48
|
+
xAxis: {
|
|
49
|
+
scaler: normalScaler,
|
|
50
|
+
step: normalStep,
|
|
51
|
+
direction,
|
|
52
|
+
controlStep,
|
|
53
|
+
controlDragScaler,
|
|
54
|
+
},
|
|
49
55
|
yAxis: { scaler: yScaler, isClipAxis, clipValue },
|
|
50
56
|
triggerEvents,
|
|
51
|
-
isControlChart
|
|
57
|
+
isControlChart,
|
|
52
58
|
}) => {
|
|
53
59
|
const step = isControlChart ? controlStep : normalStep;
|
|
54
60
|
const xScaler = isControlChart ? controlDragScaler : normalScaler;
|
|
@@ -120,7 +126,8 @@ export default memo(
|
|
|
120
126
|
}
|
|
121
127
|
|
|
122
128
|
// const y2 = yScaler(isVertical ? start : end);
|
|
123
|
-
const positionX =
|
|
129
|
+
const positionX =
|
|
130
|
+
xScaler(x) - step / 2 + seriesStart + index * seriesStep;
|
|
124
131
|
|
|
125
132
|
if (isNaN(positionX)) return null;
|
|
126
133
|
const position = isXRepeat
|