react-timeseries-charts icon indicating copy to clipboard operation
react-timeseries-charts copied to clipboard

YAxis tickCount not working as expected

Open Fxlr8 opened this issue 7 years ago • 23 comments

Hi, I found that when I change YAxis tickCount prop it works improperly. Here is a line chart with a brush.

Here tickCount is not set for both chart and brush image

Here tickCount is set to 5 for both charts image

Here tickCount is set to 2 for both charts image

As you can see it works weirdly for both charts. For the bottom one, it distributes ticks unevenly. I expected the only two ticks to be at the top and the bottom most parts of the scale. For the top one, it just doesn't make any sence.

I am using the latest version 0.12.8 Here is the component's source code

Fxlr8 avatar Aug 02 '17 12:08 Fxlr8

@sartaj10 can you take a look at this.

pjm17971 avatar Aug 06 '17 23:08 pjm17971

Doesn't seem to be working for me. tickCount={2}

image

     <Resizable>
        <ChartContainer
          timeRange={timerange}
          enablePanZoom={true}
          showGrid={false}
          showGridPosition="under"
          maxTime={timerange.end()}
          minTime={timerange.begin()}
          minDuration={1000}
          format={"%Ss"}
          timeAxisTickCount={5}
        >
          <ChartRow
            height={"250"}
          >
            <YAxis
              id={"yAxis"}
              label={this.props.format.yAxisLabel}
              labelOffset={-8}
              min={this.globalMaxMin(timeSeries).min} max={this.globalMaxMin(timeSeries).max}
              width={60}
              type="linear"
              tickCount={2}
              format={this.props.format.yAxisFormat}
            />
            <Charts>
              <LineChart
                axis={`yAxis`}
                series={timeSeries}
                columns={timeSeries.columns()}
                style={style}
              />
              <ScatterChart
                axis={`yAxis`}
                series={timeSeries}
                columns={timeSeries.columns()}
              />
            </Charts>
          </ChartRow>
        </ChartContainer>
      </Resizable>

davegravy avatar Mar 27 '18 17:03 davegravy

Let me look into it and get back to you

sartaj10 avatar Mar 27 '18 17:03 sartaj10

@davegravy Hey david, I'm not sure why it's not working on your end. It seems to be working for me. I believe you're using the latest code.

TickCount = 3 screen shot 2018-05-08 at 10 27 07 pm

TickCount = 7 screen shot 2018-05-08 at 10 28 08 pm

sartaj10 avatar May 09 '18 05:05 sartaj10

I am pinned to commit #0115315d475dee6877bf1f274d8d838cb4af068f, which should have the Yaxis tickcount fix in it.

Maybe the following would be helpful:

In my application the chart is loaded, and the timeSeries has events appended to it every second. I can see the initial render has the correct number of Yaxis ticks, but the first update to the timeSeries introduces many more ticks.

davegravy avatar May 09 '18 13:05 davegravy

@sartaj10 presumably that means there's an inconsistency between renderAxis() and updateAxis() in YAxis. A quick scan of that code seems to confirm that.

pjm17971 avatar May 09 '18 13:05 pjm17971

@davegravy

I think the issue was with the updateAxis() code which was causing this issue. I have a fix in the branch fix-175 Can you use that branch in your package.json and see if that solves the issue?

"react-timeseries-charts": "git+https://github.com/esnet/react-timeseries-charts.git#fix-175"

sartaj10 avatar May 09 '18 17:05 sartaj10

With that version when starting my development server (npm start) I get:

Failed to compile.

./node_modules/react-timeseries-charts/lib/components/ChartRow.js Module not found: Can't resolve 'react-hot-loader' in 'C:\SourceGit\dash-react\node_modules\react-timeseries-charts\lib\components'

...doesn't happen with the previous version I was pinned to

davegravy avatar May 09 '18 18:05 davegravy

You'll have to do a npm install / yarn install first for that. It's a new package that was added to package.json recently

sartaj10 avatar May 09 '18 18:05 sartaj10

npm install or npm install react-hot-loader --save? The former didn't resolve anything where the latter installed the package but produced an error:

npm ERR! Object.entries is not a function

UPDATE seems to have resolved after updating Node.

In any case my server does now start however the ticks do not appear to behave any differently with fix-175

davegravy avatar May 09 '18 18:05 davegravy

@davegravy Give it a shot once again. Updated a couple other things. Should be working now

sartaj10 avatar May 09 '18 21:05 sartaj10

Here is what I'm getting now capture

Correct # of ticks now (3) but strange selection of ticks for the plot on the right, I'm assuming there are 3 ticks on the left too but they are all bunched together at 0.

davegravy avatar May 09 '18 22:05 davegravy

I'm guessing you can't reproduce it? Maybe I can put something together. Do you have a JSFiddle template somewhere I could start from?

davegravy avatar May 10 '18 14:05 davegravy

I tried to load react-timeseries-charts into JSFiddle via unpkg but JSFiddle complained that exports was not defined. If you know another way please share :)

davegravy avatar May 10 '18 14:05 davegravy

@davegravy Hey, unfortunately, we don't have a JSFiddle template. I remember someone used codesandbox (https://codesandbox.io/) to demonstrate an example to us.

Here's the link for that - https://codesandbox.io/s/3j0540mo5 Maybe this would be helpful. Please use the master branch in your package.json rather than v0.14.0

In package.json, "react-timeseries-charts": "esnet/react-timeseries-charts"

sartaj10 avatar May 10 '18 16:05 sartaj10

@sartaj10 I changed the package.json and codesandbox responds:

× Error Could not fetch dependencies, please try again in a couple seconds: Could not fetch version for @https://github.com/esnet/react-timeseries-charts.git#master: ENOENT: no such file or directory, open '/var/task/@https:/github.com/esnet/react-timeseries-charts.git#master/package.json'

davegravy avatar May 10 '18 16:05 davegravy

Yeah, in the package.json, include the library as follows

"react-timeseries-charts": "esnet/react-timeseries-charts"

This should work. It's how this works as well - https://codesandbox.io/s/3j0540mo5

sartaj10 avatar May 10 '18 16:05 sartaj10

OK, got it:

https://codesandbox.io/s/myj2x2n7mx

davegravy avatar May 10 '18 19:05 davegravy

Thanks for this. I'll look into it more and see what's going wrong!

sartaj10 avatar May 10 '18 20:05 sartaj10

@pjm17971 Maybe you could take a look at it whenever you get some time

sartaj10 avatar May 11 '18 15:05 sartaj10

I'm running into a similar issue when I change the max of a YAxis dynamically, using the default formatter of .2s: if the max changes by enough orders of magnitude to affect the SI prefix of the result, the new prefix isn't used.

For example, if I first render the chart with a max of 1 (say, because I haven't fetched any data), then fetch my data, then calculate a max (say 3000000000), then the labels on the YAxis update, but they don't get re-formatted, so they say 3000000000 instead of 3G.

I think the problem might be in componentWillReceiveProps, here: https://github.com/esnet/react-timeseries-charts/blob/master/src/components/YAxis.js#L146

You'll see it isn't calling renderAxis if the tickCount, min or max props change. There may also be other prop changes which should trigger a re-render of the axis: you'd have to audit what props you're referencing in that method and make sure you're checking them for changes when re-rendering.

spiralman avatar Jul 14 '18 15:07 spiralman

Any update on this ticket? Running into same issue when try to dynamically render YAxis, the new range doesn't get updated in yaxis after applying tickCount, the YAxis messed up after that

renhax avatar Jan 09 '19 02:01 renhax

Found the following while looking into 0.61.1 YAxis regarding the tickCount prop anomaly though they may very well apply to all YAxis props update:

Only the componentDidMount hook is called. The component cannot render prop updates thereafter. On tickCount prop update, the componentWillReceiveProps is never called. The component is not updated. The shouldComponentUpdate is called but always returns false. When set to return true, the component is not updated.

Workaround: calculate a reasonable tickCount based on the y column data and the axis height in pixels before rendering the chart. You may suspend chart rendering: temporary render a Loader component in its place until the y column data is ready, calculate the tickCount and then render the chart.

Proposal: make componentWillReceiveProps operational. Allow the parent component to pass a Boolean prop for the shouldComponentUpdate hook e.g.

shouldComponentUpdate({isUpdatable=false}) {
    return isUpdatable;
}

There is also the react-hooks paradigm if bandwidth permits.

steveswork avatar Jun 12 '22 16:06 steveswork