I’m trying to create a “custom” apache echarts component that acts as a timeline for a series of events. However, I managed to do everything but to get the labels to show. Here’s my script:
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption({
grid: {
containLabel: true,
},
width: 1300,
});
fetch('data.json')
.then(response => response.json())
.then(data => {
data.sort((a, b) => new Date(a.date) - new Date(b.date));
const uniqueDates = [...new Set(data.map(item => item.date))];
uniqueDates.sort((a, b) => new Date(a) - new Date(b));
const startDate = new Date(uniqueDates[0]);
const endDate = new Date(uniqueDates[uniqueDates.length - 1]);
const allDates = [];
for (let dt = new Date(startDate); dt <= endDate; dt.setDate(dt.getDate() + 1)) {
allDates.push(dt.toISOString().split('T')[0]);
}
const groupedByDate = data.reduce((acc, curr) => {
if (!acc[curr.date]) {
acc[curr.date] = [];
}
acc[curr.date].push(curr);
return acc;
}, {});
Object.keys(groupedByDate).forEach(date => {
groupedByDate[date].forEach((item, index) => {
item.value[0] = allDates.indexOf(date);
item.value[1] = index;
});
});
const processedData = Object.values(groupedByDate).flat();
var option = {
tooltip: {
trigger: 'item',
formatter: function (params) {
if (params.name && params.value[2] && params.value[2].detail) {
return params.name + '<br/>' + params.value[2].detail;
}
return params.name;
},
axisPointer: {
type: 'cross'
},
},
xAxis: {
type: 'category',
data: allDates
},
yAxis: {
type: 'value',
show: false
},
dataZoom: [{
type: 'inside',
xAxisIndex: [0, 1],
start: 0,
end: 100
}, {
show: true,
xAxisIndex: [0, 1],
type: 'slider',
bottom: 30,
start: 0,
end: 100
}],
series: [{
type: 'custom',
renderItem: function (params, api) {
const currentData = data[params.dataIndex];
const yValue = api.value(1);
const start = api.coord([api.value(0), yValue]);
const size = currentData.size || api.size([0, 1]);
const style = {
fill: currentData.color || '#000'
};
return {
type: 'group',
children: [
{
type: 'rect',
shape: {
x: start[0] - size[0] * 0.4,
y: start[1] - size[1] / 2,
width: size[0] * 0.8,
height: size[1] / 2
},
style: style
}
]
};
},
name: 'Events',
barWidth: '20%',
data: processedData,
animation: true,
label: {
show: true,
position: 'inside',
formatter: 'test', // Hardcoding 'test' as the label text for testing
fontWeight: 'medium',
color: '#fff',
shadowColor: '#000',
shadowBlur: 2,
shadowOffsetX: 1,
shadowOffsetY: 1
}
}]
};
myChart.setOption(option);
})
.catch(error => {
console.error('Error fetching the data:', error);
});
</script>
Here’s what it looks like now:
I tried to add the table in the custom render function like this:
return {
type: 'group',
children: [
{
type: 'rect',
shape: {
x: start[0] - size[0] * 0.4,
y: start[1] - size[1] / 2,
width: size[0] * 0.8,
height: size[1] / 2
},
style: style
},
{
type: 'text',
style: {
text: currentData.name,
x: start[0],
y: start[1] - size[1] / 4,
textAlign: 'center',
textVerticalAlign: 'middle',
fontWeight: 'medium',
textFill: '#fff',
textShadowColor: currentData.color || '#000',
textShadowBlur: 2,
textShadowOffsetX: 1,
textShadowOffsetY: 1
}
}
]
};
It worked but it broke other things, and it does not have the functionalties I want that are easily configured in the label