我希望这里有一些amcharts用户,可以为我遇到的问题提供帮助。
简而言之:我想强制工具提示始终显示在直线系列上的悬停点上方,即使它超出图表区域也是如此。工具提示适用于所有系列。示例可以在这里看到:
const {useRef, useState} = React;
const CHART_CONTAINER = 'campaign-budget-chart';
const CHART_COLORS = {
value1: '#05a8fa',
value2: '#ed3434',
value3: '#0ec76a',
}
function getRandomNumber(max){
return Math.floor(Math.random() * Math.floor(max))
}
const initialData = [{
timestamp: new Date(2020, 09, 25),
value1: 0,
value2: getRandomNumber(50),
value3: getRandomNumber(250),
},{
timestamp: new Date(2020, 09, 26),
value1: getRandomNumber(100),
value2: getRandomNumber(50),
value3: getRandomNumber(250),
},{
timestamp: new Date(2020, 09, 27),
value1: getRandomNumber(100),
value2: getRandomNumber(50),
value3: getRandomNumber(250),
},
{
timestamp: new Date(2020, 09, 28),
value1: getRandomNumber(100),
value2: getRandomNumber(50),
value3: getRandomNumber(250),
}];
let i = 0;
function BudgetChart() {
const chartRef = useRef(null);
const [data, setData] = useState(initialData);
const [cursor, setCursor] = React.useState({ x: 0, y: 0 });
const [cursorVisible, setCursorVisible] = React.useState(false);
function createSeries(
fieldX,
fieldY,
name,
lineColor,
) {
if (!chartRef.current) return;
console.log('Create series');
// Init series
let series = chartRef.current.series.push(new am4charts.LineSeries());
series.name = name;
series.dataFields.valueY = fieldY;
series.dataFields.dateX = fieldX;
series.strokeWidth = 3;
series.stroke = am4core.color(lineColor);
series.tooltip.pointerOrientation = 'down';
series.tooltip.background.filters.clear(); // remove shadow
series.tooltip.getFillFromObject = false;
series.tooltip.background.fill = am4core.color('#2a2b2e');
series.tooltip.background.stroke = am4core.color('#2a2b2e');
series.tooltip.label.fontSize = 12;
series.tooltip.background.pointerLength = 0;
series.tooltip.dy = -5;
series.tooltipText = '{valueY}';
series.tensionX = 0.8;
series.showOnInit = false;
// Add bullet for optimization
let circleBullet = series.bullets.push(new am4charts.CircleBullet());
circleBullet.circle.radius = 6;
circleBullet.circle.fill = lineColor;
circleBullet.circle.stroke = am4core.color('#fff');
circleBullet.circle.strokeWidth = 3;
circleBullet.propertyFields.disabled = 'optimizationTooltipDisabled';
// Set up tooltip
series.adapter.add("tooltipText", function(ev) {
var text = "[bold]{dateX}[/]\n"
chartRef.current.series.each(function(item) {
text += "[" + item.stroke.hex + "]●[/] " + item.name + ": {" + item.dataFields.valueY + "}\n";
});
return text;
});
// Bullet shadow
let shadow = circleBullet.filters.push(new am4core.DropShadowFilter());
shadow.opacity = 0.1;
}
React.useEffect(() => {
if (!chartRef.current) {
chartRef.current = am4core.create(CHART_CONTAINER, am4charts.XYChart);
chartRef.current.paddingLeft = 0;
// Add date axis
let dateAxis = chartRef.current.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.labels.template.fontSize = 12;
dateAxis.renderer.labels.template.fill = am4core.color(
'rgba(183,186,199,0.8)'
);
dateAxis.renderer.grid.template.strokeOpacity = 0;
// Add value axis
let valueAxis = chartRef.current.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.grid.template.stroke = am4core.color(
'#f0f2fa'
);
valueAxis.renderer.grid.template.strokeOpacity = 1;
valueAxis.renderer.labels.template.fill = am4core.color(
'rgba(183,186,199,0.8)'
);
valueAxis.renderer.labels.template.fontSize = 12;
// Add cursor
chartRef.current.cursor = new am4charts.XYCursor();
chartRef.current.cursor.maxTooltipDistance = -1;
// Add legend
chartRef.current.legend = new am4charts.Legend();
chartRef.current.legend.position = 'bottom';
chartRef.current.legend.contentAlign = 'left';
chartRef.current.legend.paddingTop = 20;
// Disable axis lines
chartRef.current.cursor.lineX.disabled = true;
chartRef.current.cursor.lineY.disabled = true;
// Disable axis tooltips
dateAxis.cursorTooltipEnabled = false;
valueAxis.cursorTooltipEnabled = false;
// Disable zoom
chartRef.current.cursor.behavior = 'none';
chartRef.current.cursor.events.on('cursorpositionchanged', function(ev) {
let xAxis = ev.target.chart.xAxes.getIndex(0);
let yAxis = ev.target.chart.yAxes.getIndex(0);
setCursor({
x: xAxis.toAxisPosition(ev.target.xPosition),
y: yAxis.toAxisPosition(ev.target.yPosition),
});
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// Load data into chart
React.useEffect(() => {
console.log('data ', data)
if (chartRef.current) {
chartRef.current.data = data;
Object.keys(data[0]).forEach(key => {
if(key === 'timestamp') return;
createSeries(
'timestamp',
key,
key,
CHART_COLORS[key]
);
})
}
}, [data]);
// Handle component unmounting, dispose chart
React.useEffect(() => {
return () => {
chartRef.current && chartRef.current.dispose();
};
}, []);
function handleRemoveSeries(){
setData(data.map(item => ({timestamp: item.timestamp, value1: item.value1, value2: item.value2})))
}
return (
<>
<button onClick={handleRemoveSeries}>Remove 3rd series</button>
<div
id={CHART_CONTAINER}
style={{
width: '100%',
height: '350px',
marginBottom: '50px',
}}
/>
</>
);
}
ReactDOM.render(<BudgetChart />, document.getElementById('app'));
对于图表顶部附近的所有值,工具提示尝试将自身挤压到图表区域内。根据文档:https://www.amcharts.com/docs/v4/reference/tooltip/, 重要信息:在某些情况下,例如为多个序列堆叠多个工具提示,可能会忽略“ up”和“ down”值以使工具提示重叠算法起作用。
是否可以禁用工具提示重叠算法?
答案 0 :(得分:0)
从 4.10.8
版本(在发布初始问题后发布)开始,系列工具提示上有一个属性 ignoreBounds
。