apache / apache/echarts

[Bug] 自定义图表系列,添加绘制文本件组后,通过dataZoom平移X轴,会导致渲染错乱

Open
#20,135 6 comments 0 reactions 0 assignees View on GitHub
bug pending
Dominant language
TypeScript
Stars
67.3k
Forks
19.8k
Avg merge
11d 14h
Merged PRs (30d)
8

Description

### Version

5.5.1

### Link to Minimal Reproduction

https://codesandbox.io/p/sandbox/echart-custom-vpz6xs?file=%2Fpackage.json

### Steps to Reproduce

```html

var dom = document.getElementById('container');
var myChart = echarts.init(dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
const now = dayjs()
const startDayOfMonth = dayjs(`${now.format("YYYY-MM-01")}`)
const daysOfMonth = Array(now.daysInMonth()).fill(0).map((_, idx) => {
return startDayOfMonth.add(idx, "day").format("YYYY-MM-DD")
})
const randomGet = (arr) => {
const randomIdx = Math.floor(Math.random() * arr.length)
return arr[randomIdx]
}
const randomWaybills = () => {
const waybills = []
const len = Math.ceil(Math.random() * 10)
for (let i = 0; i < len; i++) {
const t1 = randomGet(Array(31).fill(0).map((_, idx) => dayjs("2024-07-01").add(idx % 31, "day")))
const t2 = randomGet(Array(31).fill(0).map((_, idx) => dayjs("2024-07-01").add(idx % 31, "day")))
const loadTime = (t1.isBefore(t2) ? t1 : t2).format("YYYY-MM-DD")
const unloadTime = (t1.isBefore(t2) ? t2 : t1).format("YYYY-MM-DD")
waybills.push({
id: Math.ceil(Math.random() * 100000000),
// 不重复
from: randomGet(["泰州", "宿迁", "镇江", "盐城", "扬州", "盐城", "盐城", "盐城", "盐城"]),
to: randomGet([ "无锡", "常州", "南通", "扬州", "盐城", "扬州", "盐城", "盐城", "盐城", "盐城"]),
driverName: randomGet(["王麻子", "李四", "王五", "赵六", "孙七", "周八", "吴九", "王麻子"]),
escortName: randomGet(["李四", "王五", "赵六", "孙七", "周八", "吴九", "郑十", "王麻子"]),
// 时间随机在同一个月份
loadTime,
unloadTime
})
}
return waybills
}
const mockDatas = [
{
plateNo: "湘A8899590",
waybills: randomWaybills()
},
{
plateNo: "湘A8899568",
waybills: randomWaybills()
},
{
plateNo: "湘A8899569",
waybills: randomWaybills()
},
{
plateNo: "湘A8899560",
waybills: randomWaybills()
},
]
const plateNos = mockDatas.map(item => item.plateNo)

var option;

const DataType = {
Waybill: 1,
Blank: 2,
Virtual: 3
}
const serialData = [];
mockDatas.forEach(function (d, idx) {
const {waybills} = d
const placeholderDay = new Set()
for (let i = 0; i < waybills.length; i++) {
const waybill = waybills[i]
serialData.push({
value: [idx, waybill.loadTime, waybill.unloadTime, DataType.Waybill, waybill],
itemStyle: {
normal: {
color: "#ece2f5"
}
}
})
const end = dayjs(waybill.unloadTime)
for (let start = dayjs(waybill.loadTime); start.isBefore(end) || start.isSame(end); start = start.add(1, "day")) {
placeholderDay.add(start.format("YYYY-MM-DD"))
}
}
// 构造虚拟数据点,确保xAxis类目每个点位都有数据,防止xAxis出现点位缺失
daysOfMonth.forEach(d => {
serialData.push({
value: [idx, d, d, DataType.Virtual],
itemStyle: {
silent: false,
normal: {
color: "transparent"
}
}
})
})
// 构造空白区域,实现点击新增效果
let start, end
const blankDays = daysOfMonth.map(d => placeholderDay.has(d) ? null : d)
blankDays.forEach((curr, i) => {
if (!start) {
if (curr) {
start = curr
end = curr
}
return
} else if (curr) {
end = curr
}
if (curr == null || i === blankDays.length - 1) {
serialData.push({
value: [idx, start, end, DataType.Blank, d],
itemStyle: {
normal: {
color: "transparent"
}
}
})
start = null
end = null
}
})
})

function renderItem(params, api) {
if (api.value(3) === DataType.Virtual) {
return
}
const truckIndex = api.value(0)
const drawStart = api.coord([api.value(1), truckIndex])
const drawEnd = api.coord([api.value(2), truckIndex])
const drawHeight = api.size([0, 1])[1] * 0.85
const oneTickWidth = api.size([1, 0])[0]
if (api.value(3) === DataType.Blank) {
return {
type: 'rect',
shape: echarts.graphic.clipRectByRect(
{
x: drawStart[0] - oneTickWidth / 2,
y: drawStart[1] - drawHeight / 2,
width: drawEnd[0] - drawStart[0] + oneTickWidth,
height: drawHeight,
},
{
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
}
),
style: {
fill: "transparent"
},
}
}
let rectHead = echarts.graphic.clipRectByRect(
{
x: drawStart[0] - oneTickWidth / 2,
y: drawStart[1] - drawHeight / 2,
width: 6,
height: drawHeight,
},
{
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
}
);
const rectShape = echarts.graphic.clipRectByRect(
{
x: drawStart[0] - oneTickWidth / 2 + 6,
y: drawStart[1] - drawHeight / 2,
width: drawEnd[0] - drawStart[0] + oneTickWidth - 6,
height: drawHeight,
},
{
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
}
);
const children = []
if (rectHead) {
children.push({
type: 'rect',
shape: {...rectHead, r: [2, 0, 0, 2]},
style: {
fill: "#7c3bb4"
},
z2: 99
})
}
if (rectShape) {
children.push(...[
{
type: 'text',
style: {
text: "上海~广州"
},
x: drawStart[0] - oneTickWidth / 2 + 6 + 8,
y: drawStart[1] - drawHeight / 2 + 8,
z2: 100,
},
{
type: 'rect',
shape: {...rectShape, r: [0, 2, 2, 0]},
style: {
fill: "#ece2f5"
},
}
])
}
if (children.length > 0) {
return {
type: "group",
children: children
}
}
}

option = {
tooltip: {
formatter: function (params) {
if (params.value[3] === DataType.Waybill) {
const waybill = params.value[4]
return params.marker + waybill.from + "~" + waybill.to + "<br/>"
+ "司机: " + waybill.driverName + "&nbsp;&nbsp;"
+ "押运员: " + waybill.escortName + "<br/>";
} else if (params.value[3] === DataType.Blank) {
return "新增运单";
}

}
},
title: {
text: 'Test',
left: 'center'
},
dataZoom: [
{
type: 'inside',
filterMode: 'weakFilter',
minValueSpan: 1,
maxValueSpan: 7,
xAxisIndex: 0,
}
],
grid: {
height: 500
},
xAxis: {
value: daysOfMonth,
position: "top",
type: "category"
},

yAxis: {
data: plateNos
},
series: [
{
type: 'custom',
renderItem,
encode: {
x: [1, 2],
y: 0
},
data: serialData.sort((a, b) => a.value[1].localeCompare(b.value[1])),
barWidth: "100%"
}
]
};

myChart.setOption(option);

```

### Current Behavior

当我在自定义组件中,添加了文本组件,初始化的时候图表的渲染是正常的,但是当我尝试移动x轴,图表渲染会出现混乱。
如下图:
【初始化的时候,正常显示】
image

【当我移动x轴时,原本应该绘制在坐标轴内的矩形,出现在了外面】
image

【当我注释掉绘制的文本组件的代码,图表会正常的渲染,绘制的矩形不会出现在坐标轴外】
image

### Expected Behavior

我不明白为什么我添加一个简单的文本组件后,它会让原本正常绘制的矩形出现在坐标轴外

### Environment

```markdown
- OS:macOS 14.3.1
- Browser: Chrome 126.0.6478.127(正式版本) (arm64)
- Framework: HTML+JavaScript
```

### Any additional comments?

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.