react-native-chart-kit
                                
                                 react-native-chart-kit copied to clipboard
                                
                                    react-native-chart-kit copied to clipboard
                            
                            
                            
                        How to use decorator for line chart - (show a tooltip onDataPointClick)
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 ?
@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