Search code examples
javascriptreactjsd3.jsreact-vis

How to reverse/descend/sort x-axis data in react-vis


I haven't been able to find this looking around the documentation. I'd like to show a graph with the x-axis rendering Dates & Times with the most recent data on the left. I had hoped that just reversing the data property array would do it but the react-vis library is smarter than that.

I would have thought the information is on this documentation page.

So, how do I sort the x-axis descending?

Code Sample

function ExampleGraph(props) {
  const {
    data,
    x, y,
  } = props

  // const keys = Object.keys(data)
  // if(keys.length>2){
  //   console.error({data}, "has too many dimensions for x-y")
  // }
  const keys=[x,y]

  const xyData = (()=> {
    const xKey = keys[0]
    const yKey = keys[1]

    const xArgs = data.map(r => (r[xKey]))
    const yArgs = data.map(r => (r[yKey]))

    const coords = xArgs.map((x, i) => ({
      x: x,
      y: yArgs[i] 
    }))

    return coords
  })()

  return (
    <XYPlot
    width={1000}
    height={640}>
      <HorizontalGridLines />
      <LineSeries
        data={xyData}
      />
      <XAxis />
      <YAxis />
    </XYPlot>
  )
}

BlazeJS (MeteorJS) template that renders the component

<template name="stepCountsGraph">
  <div>
    {{> React
      component=ExampleGraph
      data=stepCounts
      y="step_count"
      x="time"
    }}
  </div>
</template>

Solution

  • You should be able to reverse the xDomain by specifying it! react-vis accepts a variety of props for each dimension (eg xDomain/xRange/xType and yDomain/yRange/yType), so if you want to control the exact layout of your chart you can specify some or all of these properties. In order to achieve the reversed domain effect you are describing you could modify you fragment to be something like this

    function ExampleGraph() {
    const xKey = this.props.x;
    const yKey = this.props.y;
    const xyData = data.map(r => ({x: r[xKey], y: r[yKey]}));
    const xDomain = data.reduce((res, row) => {
        return {max: Math.max(res.max, row[xKey]), min: Math.min(res.min, row[xKey])};
    }, {min: Infinity, max: -Infinity});
    
    return (
    <XYPlot
        xDomain={[xDomain.max, xDomain.min]}
        width={1000}
        height={640}>
          <HorizontalGridLines />
          <LineSeries data={xyData} />
          <XAxis />
          <YAxis />
        </XYPlot>
       )
    }
    

    I hope that answers your question! I've open an issue to add this type of clarification to the docs here.