Open luatnd opened 5 years ago
@luatnd I also need to create the tooltip as the forecast X axis labels disappears depending on the chart hight
@fabriziobertoglio1987 I need to clone this repository to my local machine, then modify the code manually :D Unfortunately, I modify too much to gain my project's requirement - so I cannot contribute back. Below is how I make the tooltip:
@luatnd Can you please share me the code of tooltip or how can I render it on the dot?
@shariqahmed1 I upload to my fork repos, be aware that I've modified it to much so it's might different from this origin repo. https://github.com/luatnd/react-native-chart-kit
Here is how I use it:
const lineChartData = {"labels":[],"datasets":[{"data":[13.8,13.8,13.8,13.8,13.8,13.8,13,13.8,13.8,13.8,13.8],"strokeWidth":1,"labels":[1566201802,1566288253,1566374595,1566460963,1566547429,1566806673,1566892961,1566892961,1566979498,1567065874,1567152215]}]};
<LineChart
ref={this.refLine}
data={lineChartData}
withDots={true}
withHiddenDots={true}
withShadow={true}
width={Dimensions.get('window').width - 10} // from react-native
height={175}
yAxisLabel={''}
yAxisLabelVisible={false}
chartConfig={chartConfig}
bezier
withInnerLines={false}
withOuterLines={false}
style={s.lineChart}
getTooltipTextX={this.getTooltipTextXLine}
getTooltipTextY={this.getTooltipTextYLine}
onChartClick={this.onLineChartPressIn}
// onRendered={this.onRenderedLine}
/>
// Tooltip: show date and stock price
getTooltipTextXLine = (i, v, dataset) => moment(dataset.labels[i] * 1000).format('ddd, DD/MM, HH:mm:ss');
getTooltipTextYLine = (i, v, dataset) => I18n.t('stock.price') + ': ' + v;
@boundMethod // use external npm package to autobind this
onLineChartPressIn(index, x,y) {
if (this.BarChart) {
const firstDataset = this.state.barChartData.datasets[0];
this.BarChart.handleChartClickByIndex(index, x, y, firstDataset); // Simulate the clicked event so that bar chart can show tooltip when we click on LineChart
}
}
Charts was modified to handle and show tooltip internally. You can read my latest commit, sorry about a bunch of code in only 1 commit ^^
@luatnd Thank you so much I try this
Here is an example of type of HOC to add tooltips using LineChart component. It's inspired on the @luatnd solution.
import PropTypes from 'prop-types';
import React, { useState } from 'react';
import { Circle, G, Rect, Text } from 'react-native-svg';
import { Dimensions } from 'react-native';
import { LineChart } from 'react-native-chart-kit';
const screenWidth = Dimensions.get('window').width;
const Tooltip = ({ x, y, textX, textY, stroke, pointStroke, position }) => {
let tipW = 136,
tipH = 36,
tipX = 5,
tipY = -9,
tipTxtX = 12,
tipTxtY = 6;
const posY = y;
const posX = x;
if (posX > screenWidth - tipW) {
tipX = -(tipX + tipW);
tipTxtX = tipTxtX - tipW - 6;
}
const boxPosX = position === 'left' ? posX - tipW - 10 : posX;
return (
<G>
<Circle
cx={posX}
cy={posY}
r={4}
stroke={pointStroke}
strokeWidth={2}
fill={'blue'}
/>
<G x={boxPosX < 40 ? 40 : boxPosX} y={posY}>
<Rect
x={tipX + 1}
y={tipY - 1}
width={tipW - 2}
height={tipH - 2}
fill={'rgba(255, 255, 255, 0.9)'}
rx={2}
ry={2}
/>
<Rect
x={tipX}
y={tipY}
width={tipW}
height={tipH}
rx={2}
ry={2}
fill={'transparent'}
stroke={stroke}
/>
<Text x={tipTxtX} y={tipTxtY} fontSize="10" textAnchor="start">
{textX}
</Text>
<Text
x={tipTxtX}
y={tipTxtY + 14}
fontSize="12"
textAnchor="start">
{textY}
</Text>
</G>
</G>
);
};
Tooltip.propTypes = {
x: PropTypes.func.isRequired,
y: PropTypes.func.isRequired,
height: PropTypes.number,
stroke: PropTypes.string,
pointStroke: PropTypes.string,
textX: PropTypes.string,
textY: PropTypes.string,
position: PropTypes.string,
};
Tooltip.defaultProps = {
position: 'rigth',
};
const tooltipDecorators = (state, data, valueFormatter) => () => {
if (state === null) {
return null;
}
const { index, value, x, y } = state;
const textX = data.labels[index];
console.log(data.labels);
const position = data.labels.length === index + 1 ? 'left' : 'right';
return (
<Tooltip
textX={String(textX)}
textY={valueFormatter(value)}
x={x}
y={y}
stroke={'#00ccff'}
pointStroke={'#00ccff'}
position={position}
/>
);
};
const LineChartWithTooltips = ({ valueFormatter, ...props }) => {
const [state, setState] = useState(null);
return (
<LineChart
{...props}
decorator={tooltipDecorators(state, props.data, valueFormatter)}
onDataPointClick={setState}
/>
);
};
LineChartWithTooltips.propTypes = {
valueFormatter: PropTypes.func,
};
LineChartWithTooltips.defaultProps = {
valueFormatter: value => String(value),
};
export default LineChartWithTooltips;
Hi.. I wrote one in detail check this https://medium.com/@mohitkaushik2468/adding-tooltip-to-react-native-charts-67606c5d3182
Here is an example of type of HOC to add tooltips using LineChart component. It's inspired on the @luatnd solution.
import PropTypes from 'prop-types'; import React, { useState } from 'react'; import { Circle, G, Rect, Text } from 'react-native-svg'; import { Dimensions } from 'react-native'; import { LineChart } from 'react-native-chart-kit'; const screenWidth = Dimensions.get('window').width; const Tooltip = ({ x, y, textX, textY, stroke, pointStroke, position }) => { let tipW = 136, tipH = 36, tipX = 5, tipY = -9, tipTxtX = 12, tipTxtY = 6; const posY = y; const posX = x; if (posX > screenWidth - tipW) { tipX = -(tipX + tipW); tipTxtX = tipTxtX - tipW - 6; } const boxPosX = position === 'left' ? posX - tipW - 10 : posX; return ( <G> <Circle cx={posX} cy={posY} r={4} stroke={pointStroke} strokeWidth={2} fill={'blue'} /> <G x={boxPosX < 40 ? 40 : boxPosX} y={posY}> <Rect x={tipX + 1} y={tipY - 1} width={tipW - 2} height={tipH - 2} fill={'rgba(255, 255, 255, 0.9)'} rx={2} ry={2} /> <Rect x={tipX} y={tipY} width={tipW} height={tipH} rx={2} ry={2} fill={'transparent'} stroke={stroke} /> <Text x={tipTxtX} y={tipTxtY} fontSize="10" textAnchor="start"> {textX} </Text> <Text x={tipTxtX} y={tipTxtY + 14} fontSize="12" textAnchor="start"> {textY} </Text> </G> </G> ); }; Tooltip.propTypes = { x: PropTypes.func.isRequired, y: PropTypes.func.isRequired, height: PropTypes.number, stroke: PropTypes.string, pointStroke: PropTypes.string, textX: PropTypes.string, textY: PropTypes.string, position: PropTypes.string, }; Tooltip.defaultProps = { position: 'rigth', }; const tooltipDecorators = (state, data, valueFormatter) => () => { if (state === null) { return null; } const { index, value, x, y } = state; const textX = data.labels[index]; console.log(data.labels); const position = data.labels.length === index + 1 ? 'left' : 'right'; return ( <Tooltip textX={String(textX)} textY={valueFormatter(value)} x={x} y={y} stroke={'#00ccff'} pointStroke={'#00ccff'} position={position} /> ); }; const LineChartWithTooltips = ({ valueFormatter, ...props }) => { const [state, setState] = useState(null); return ( <LineChart {...props} decorator={tooltipDecorators(state, props.data, valueFormatter)} onDataPointClick={setState} /> ); }; LineChartWithTooltips.propTypes = { valueFormatter: PropTypes.func, }; LineChartWithTooltips.defaultProps = { valueFormatter: value => String(value), }; export default LineChartWithTooltips;
Can you provide this solution using Component instead of Hooks? Thanks. @vsalvans
Hi I took a look at the
/src/line-chart.js
. And I can see it support decorator, but I don't know how to use it to make a tooltip when I click a data point. Is there anyone can show me an example ?