wuxudong / react-native-charts-wrapper

a react native charts wrapper (support android & iOS)
2.45k stars 659 forks source link

Inaccurate distance between datapoints on the xaxis #759

Open dstollie opened 4 years ago

dstollie commented 4 years ago

After research the the lib, messing with all the configs and going through the issues on the github of MPAndroidChart I finally chose the make a bug issue here on this github:

The problem: As seen in the screenshot of "android" you can see that the distnace between the dots (circles) are not exactly the same. If you look at the example of iOS you can see that this is not the case and that the dots perfectly alight with each other. I cannot figure out why this is the issue. On the xAxis we use timestamp, this may be the issue but as far as I can see this should work. This issue might seem like a small bug but it makes the chart really confusing because if you look closely you expect a time difference between the points when there is actually no diff.

Expected Behavior

The dots on android do have the same dinstance between each other.

Actual Behavior

Graph in IOS IMG_0002

Graph On Android (faulty) Screenshot_20201102-134209_Zonneplan

Screenshots

Data and config

Data:

const data = [
        {x: 1604310900000, y: 0, marker: "10:55: 0W"},
        {x: 1604311200000, y: 0, marker: "11:00: 0W"},
        {x: 1604311500000, y: 0, marker: "11:05: 0W"},
        {x: 1604311800000, y: 0, marker: "11:10: 0W"},
        {x: 1604312100000, y: 0, marker: "11:15: 0W"},
        {x: 1604312400000, y: 0, marker: "11:20: 0W"},
        {x: 1604312700000, y: 0, marker: "11:25: 0W"},
        {x: 1604313000000, y: 0, marker: "11:30: 0W"},
        {x: 1604313300000, y: 0, marker: "11:35: 0W"},
        {x: 1604313600000, y: 0, marker: "11:40: 0W"},
        {x: 1604313900000, y: 0, marker: "11:45: 0W"},
        {x: 1604314200000, y: 0, marker: "11:50: 0W"},
        {x: 1604314500000, y: 0, marker: "11:55: 0W"},
        {x: 1604314800000, y: 0, marker: "12:00: 0W"},
        {x: 1604315100000, y: 0, marker: "12:05: 0W"},
        {x: 1604315400000, y: 0, marker: "12:10: 0W"},
        {x: 1604315700000, y: 0, marker: "12:15: 0W"},
        {x: 1604316000000, y: 0, marker: "12:20: 0W"},
        {x: 1604316300000, y: 0, marker: "12:25: 0W"},
        {x: 1604316600000, y: 0, marker: "12:30: 0W"},
        {x: 1604316900000, y: 0, marker: "12:35: 0W"},
        {x: 1604317200000, y: 0, marker: "12:40: 0W"},
        {x: 1604317500000, y: 0, marker: "12:45: 0W"},
        {x: 1604317800000, y: 0, marker: "12:50: 0W"},
        {x: 1604318100000, y: 0, marker: "12:55: 0W"},
        {x: 1604318400000, y: 0, marker: "13:00: 0W"},
        {x: 1604318700000, y: 0, marker: "13:05: 0W"},
        {x: 1604319000000, y: 0, marker: "13:10: 0W"},
        {x: 1604319300000, y: 0, marker: "13:15: 0W"},
        {x: 1604319600000, y: 47, marker: "13:20: 47W"},
        {x: 1604319900000, y: 0, marker: "13:25: 0W"},
        {x: 1604320200000, y: 0, marker: "13:30: 0W"},
        {x: 1604320500000, y: 0, marker: "13:35: 0W"},
        {x: 1604320800000, y: 0, marker: "13:40: 0W"},
        {x: 1604321100000, y: 0, marker: "13:45: 0W"},
    ];

Config:

<StyledLineChart
    data={{
        dataSets: [{
            values: mappedData,
            label: '',
            config: {
                mode: 'HORIZONTAL_BEZIER',
                drawValues: false,
                highlightEnabled: true,
                drawHighlightIndicators: true,
                lineWidth: 1,
                drawCircles: true,
                circleRadius: 2,
                drawVerticalHighlightIndicator: true,
                drawHorizontalHighlightIndicator: false,
                circleColor: processColor(chartColor),
                drawCircleHole: false,
                highlightColor: processColor('transparent'),
                color: processColor(chartColor),
                drawFilled: true,
                fillGradient: {
                    colors: fillGradient,
                    positions: [0, 0.5],
                    orientation: 'TOP_BOTTOM',
                },
                fillAlpha: 100,
            },
        }],
    }}
    maxVisibleValueCount={1}
    highlightPerDragEnabled={true}
    chartDescription={{ text: '' }}
    legend={{ enabled: false }}
    marker={{
        enabled: true,
        markerColor: processColor(theme.tooltipColor),
        textColor: processColor(theme.tooltipTextColor),
    }}
    xAxis={{
        drawGridLines: false,
        avoidFirstLastClipping: true,
        position: 'BOTTOM',
        textColor: processColor(`${theme.chartAxisColor}`),
        textSize: 10,
        fontFamily: 'Roboto',
        valueFormatter: 'date',
        centerAxisLabels: false,
        valueFormatterPattern: 'mm',
        since: offset,
        timeUnit: 'MILLISECONDS',
        drawAxisLines: false,
        axisLineWidth: 0,
        axisLineColor: processColor('#FFFFFF00'),
        axisMinimum: minDate.unix() * 1000,
        axisMaximum: maxDate.unix() * 1000,
    }}
    yAxis={{
        left: {
            drawGridLines: false,
            gridColor: processColor(theme.chartGridStrokeColor),
            textColor: processColor(`${theme.chartAxisColor}77`),
            fontFamily: 'Roboto',
            textSize: 10,
            axisLineWidth: 0,
            labelCount: 5,
            drawAxisLines: false,
            axisLineColor: processColor('#FFFFFF00'),
            axisMinimum: 0,
            axisMaximum: yAxisMaximum,
        },
        right: {
            enabled: false,
        },
    }}
    autoScaleMinMaxEnabled={true}
    animation={props.animate ? {
        durationX: 300,
        durationY: 0,
        easingY: 'EaseInOutQuart',
    } : {}}
    drawGridBackground={false}
    drawBorders={false}
    touchEnabled={true}
    scaleXEnabled={false}
    pinchZoom={false}
    scaleYEnabled={false}
    dragEnabled={true}
    doubleTapToZoomEnabled={false}
    highlights={[
        {x: lastMappedPoint?.x, y: lastMappedPoint?.y},
    ]}
    zoom={{
        scaleX: 1,
        scaleY: 1,
        xValue: lastMappedPoint?.x || 0,
        yValue: lastMappedPoint?.y || 0,
        axisDependency: 'RIGHT',
    }}
/>

Steps to Reproduce the Problem

Specifications

ray-aoms commented 1 year ago

I am facing the same issue: Left is iOS, right is Android

Screenshot 2023-02-10 at 4 52 24 PM
wuxudong commented 1 year ago

That may be caused by number precision. x value is float in android and double in iOS.

So using unix timestamp as x may cause precision problem, there are some workarounds:

  1. use other timeUnit, for example MINUTES, check config lib/AxisIface.js

    timeUnit: PropTypes.oneOf(['MILLISECONDS', 'SECONDS', 'MINUTES', 'HOURS', 'DAYS']), // timeUnit of x,

  2. You can also combine since, for example since = new Date('2020-01-01 00:00:00').getTime()

the final displayed date will be

     since + x * timeUnit