More DRY way of conditionally filling variables? I'm building a chart component and it behaves differently if data has been passed in or not.
Here are two ways I can think of to conditionally fill chart variables.
(data will be empty {} or have non-empty values)
// helper
function isEmptyObject(obj) {
  for (const i in obj) return false;
  return true;
}

const gridInterval = 5;

let yTopTickValue;
let yBottomTickValue;
let yTickCount;
let xTopTickValue;
let xBottomTickValue;
let xTickCount;

if (!isEmptyObject(data)) {
  yTopTickValue = Math.ceil(data.yMax / gridInterval) * gridInterval;
  yBottomTickValue = Math.floor(data.yMin / gridInterval) * gridInterval;
  yTickCount = (yTopTickValue - yBottomTickValue) / gridInterval + 1;

  xTopTickValue = Math.ceil(data.yMax / gridInterval) * gridInterval;
  xBottomTickValue = Math.floor(data.yMin / gridInterval) * gridInterval;
  xTickCount = (xTopTickValue - xBottomTickValue) / gridInterval + 1;
}

and
const gridInterval = 5;
const isDataEmpty = isEmptyObject(data);

const yTopTickValue = isDataEmpty ? null: Math.ceil(data.yMax / gridInterval) * gridInterval;
const yBottomTickValue = isDataEmpty ? null: Math.floor(data.yMin / gridInterval) * gridInterval;
const yTickCount = isDataEmpty ? null: (yTopTickValue - yBottomTickValue) / gridInterval + 1;

const xTopTickValue = isDataEmpty ? null: Math.ceil(data.yMax / gridInterval) * gridInterval;
const xBottomTickValue = isDataEmpty ? null: Math.floor(data.yMin / gridInterval) * gridInterval;
const xTickCount = isDataEmpty ? null: (xTopTickValue - xBottomTickValue) / gridInterval + 1;

Are there any other clever versions I'm missing?
Since you have a reasonable number of variables that all relate to one particular thing (chart settings), rather than having lots of standalone variables, you might consider using a single object instead. Regardless of any other issues with the code, I'd consider a single object to be slightly more appropriate than multiple similar standalone variables regardless.
Using a single object can also let you exploit a shortcut: if data doesn't exist, just use an empty object. Otherwise, type out the object literal using your formulas:
const getChartSettings = (gridInterval, data) =&gt; {
  if (isEmptyObject(data)) {
    return {};
  }
  const yTopTickValue = Math.ceil(data.yMax / gridInterval) * gridInterval;
  const yBottomTickValue = Math.floor(data.yMin / gridInterval) * gridInterval;
  const xTopTickValue = Math.ceil(data.yMax / gridInterval) * gridInterval;
  const xBottomTickValue = Math.floor(data.yMin / gridInterval) * gridInterval;
  return {
    yTopTickValue,
    yBottomTickValue,
    yTickCount : (chartSettings.yTopTickValue - chartSettings.yBottomTickValue) / gridInterval + 1,
    xTopTickValue,
    xBottomTickValue,
    xTickCount : (chartSettings.xTopTickValue - chartSettings.xBottomTickValue) / gridInterval + 1,
  };
};

Then you can call the function, reference chartSettings.yBottomTickValue, and either get a number or undefined.
YMMV on whether that's worth using or not.
It's unfortunate that the TickCounts depend on the prior calculated values - if they didn't, it could be made to look a lot simpler by just returning the single object literal instead of defining variables beforehand.
You could still return an object alone without prior defined variables by making the TickCounts getters instead, but that'd be weird-looking, I wouldn't use it:
return {
  yTopTickValue: Math.ceil(data.yMax / gridInterval) * gridInterval,
  yBottomTickValue: Math.floor(data.yMin / gridInterval) * gridInterval,
  get yTickCount() {
    return (this.yTopTickValue - this.yBottomTickValue) / gridInterval + 1;
  },
  // ...

Operator position You also might consider putting the + 1 at the beginning, rather than at the end, eg:
xTickCount : 1 + (chartSettings.xTopTickValue - chartSettings.xBottomTickValue) / gridInterval,

I think that's a bit clearer than putting it right next to the / gridInterval. You could also consider using no-mixed-operators.