I am working on a data visualization project using Apache ECharts and I've encountered an issue with setting the x-axis limit for my markLine. I want to draw mark lines that span specific portions of the chart, not the entire width. My goal is to highlight specific sections of my data for better analysis.
The first image is what my code generates right now. The second image what i am trying to make. Note that in second image have the defined width of the horizontal markline.
var data = [
['Event 1', '02:00'],
['Event 2', '11:30'],
['Event 3', '14:00'],
['Event 4', '16:45'],
['Event 5', '19:00'],
['Event 6', '23:30']
];
var processedData = data.map(function (item) {
return {
value: [
1,
parseInt(item[1].split(':')[0]) + parseInt(item[1].split(':')[1]) / 60
],
name: item[0]
};
});
console.log(processedData);
var option = {
tooltip: {
trigger: 'axis',
formatter: function (params) {
var event = params[0];
return (
event.marker +
event.name +
'<br>' +
event.value[1].toFixed(2) +
' hours'
);
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: [''],
axisLine: { show: true },
axisTick: { show: false },
axisLabel: { show: false }
},
yAxis: {
type: 'value',
min: 0,
max: 24,
splitLine: { show: false },
axisLabel: {
formatter: function (value) {
var hours = Math.floor(value);
var minutes = (value - hours) * 60;
return (
(hours < 10 ? '0' + hours : hours) +
':' +
(minutes < 10 ? '0' + minutes.toFixed(0) : minutes.toFixed(0))
);
}
}
},
series: [
{
type: 'line',
data: processedData,
coordinateSystem: 'cartesian2d',
symbolSize: 15,
symbol: 'circle',
itemStyle: {
normal: {
color: '#1f77b4'
}
},
lineStyle: {
normal: {
opacity: 0.5
}
},
step: 'middle',
markLine: {
silent: true,
symbol: ['none', 'none'],
lineStyle: {
type: 'solid',
color: '#333'
},
data: processedData.flatMap((item) => [
{
name: item.name,
x: '53%',
yAxis: item.value[1]
}
])
}
}
]
};
EDIT:
If you use the the markLine data
property coord you can specify points in your respective coordinate system coordinates.
markLine: {
data: processedData.flatMap((item, index) => [
[
{name: item.name, coord: [1, item.value[1]]},
{coord: [index % 2 ? 0.2 : 1.8, item.value[1]]}
]
])
}
Previous Answer:
You can entirely specify the markLine data as a list of two points of pixel coordinates. The basic structure looks like this (see also this stackoverflow post):
markLine: {
data: [
[
{x: 10, y: 20},
{x: 20, y: 30}
]
]
}
To get you cartesian coordinates as pixel coordiantes you can use convertToPixel.
Additionally, you used axis type 'category' for your xAxis which will not give reasonable pixel coordinates (since you can only have integer values). I replaced it with type 'value' and added min: 0
and max: 2
to restrict it to the same window as in 'category'.
Now you just change one of the xaxis coordinates based on the index of your data array:
markLine: {
data: processedData.flatMap((item, index) => [
[
{
name: item.name,
x: myChart.convertToPixel({ xAxisIndex: 0 }, 1),
y: myChart.convertToPixel({ yAxisIndex: 0 }, item.value[1])
},
{
x: myChart.convertToPixel({ xAxisIndex: 0 }, index % 2 ? 0.2 : 1.8),
y: myChart.convertToPixel({ yAxisIndex: 0 }, item.value[1])
}
]
])
}
And here is your revised example (note, that the markLine is added in a separate step because before the chart is initialized you cant use the convertToPixel
method).