Line chart x-axis not sorted

Hi there,
I have line chart with date time in x-axis, but not sorted well. Did I miss someting?

Below for the screenshot. I rotate it so you can see x-axis easily.

Hi @erikon7,

I've seen something like this before, though I've only used charts a few times. I think there are a couple reasons for it. For starters, the chart component itself didn't handle sorting, it relied on the data - to you'll need to ensure the keys in your data objects are sorted.

You can sort the keys with something like this:

function sortKeysInArray(arrayOfObjects) {
  return arrayOfObjects.map(obj => {
    return Object.keys(obj).sort().reduce((sortedObj, key) => {
      sortedObj[key] = obj[key];
      return sortedObj;
    }, {});
  });
}

// Example usage
const arrayOfObjects = [
  { z: 1, a: 2, b: 3 },
  { c: 4, d: 5, a: 6 }
];

const sortedArray = sortKeysInArray(arrayOfObjects);

I also ran into an issue where it sorted them based on the keys, but if every object didn't have the same keys, it would append them to the end, so it would build based on sort order, but eventually it would get out of order IF the keys weren't consistent. If you run into that, then this function can merge all the keys into each object and sort them:

function normalizeAndSortKeys(arrayOfObjects) {
  // Get all unique keys from all objects
  const allKeys = Array.from(new Set(arrayOfObjects.flatMap(Object.keys))).sort();

  // Normalize each object to include all keys, with null for missing keys
  return arrayOfObjects.map(obj => {
    return allKeys.reduce((normalizedObj, key) => {
      normalizedObj[key] = obj[key] !== undefined ? obj[key] : null;
      return normalizedObj;
    }, {});
  });
}

// Example usage
const arrayOfObjects = [
  { z: 1, a: 2, b: 3 },
  { c: 4, d: 5, a: 6 }
];

const normalizedSortedArray = normalizeAndSortKeys(arrayOfObjects);
console.log(normalizedSortedArray);
// Logs out
[
  { a: 2, b: 3, c: null, d: null, z: 1 },
  { a: 6, b: null, c: 4, d: 5, z: null }
]
1 Like

i made a quick sort function for someone else over here if ya'll need it.

const quickSort = (myArray) => {
  if (myArray.length <= 1) {
    return arr;
  }

  // this can be any of the array items, I picked the middle as it's simple.  
  // generally you want to avoid using the first or last index as the pivot as it increases the odds of hitting a worse-case scenario of O(n^2).  the majority of the time you'll get around O(n log(n))
  let mid = myArray.length / 2;
  let pivot = myArray[mid];

  let leftArray = [];
  let rightArray = [];

  for (let i = 1; i < myArray.length; i++) {
    // sort numeric values
    else{
      if (myArray[i] < pivot) {
        leftArray .push(myArray[i]);
      } else {
        rightArray .push(myArray[i]);
      }
    }
  }

  return [...quickSort(leftArray ), pivot, ...quickSort(rightArray )];
};

removed custom 'string' stuff the person needed so now it's back to a normal quick sort

2 Likes

I think we have missunderstanding about the issue and those solutions doesn't work. The problem is some of my data is missing and made the chart re-order the data.
I found exactly same issue here but it is in python. I don't know how to implement in retool.
Any advise?

ok so let me see if i've got this right. you have a set of data, which you have already ordered a specific way possibly containing missing values. when you use plotly to make the line chart it reorders your data because of this missing data (I'm guessing it's moving the empty ones to the end of the your ordered data, like in the link you posted?).

so the problem isn't sorting anything, it's keeping plotly from changing the order? did i get that right?

you also mentioned the solution from the link you gave is what you're trying to use but can't figure out how?

fg.update_layout(xaxis={'categoryorder':'category ascending'})

is this what you're refering to when you say:

1 Like

:wave: It would be helpful to get confirmation on the above.

A json export with data could be helpful as well

Otherwise, it might help to try other x axis types: