billboard.js icon indicating copy to clipboard operation
billboard.js copied to clipboard

Ordering of columns in Bar chart is broken

Open creage opened this issue 4 years ago • 6 comments

Description

Bar chart data is NOT ordered as provided, despite setting order parameter to null

Steps to check or reproduce

Have a simple bar chart

var chart = bb.generate({
  data: {
    columns: [
	["30", 130],
	["20", 30],
	["10", 80]
    ],
    order: null,
    type: "bar"
  },
  bindto: "#barChart"
});

I expect column with label 30 to appear first, then 20, and then 10. Instead, I receive them ordered in 10, 20, 30 way, no matter what value I set for order parameter!

You can check it on the Examples page.

creage avatar Jan 08 '20 15:01 creage

Hi @creage, it seems having ordering issue when data names are number. Thanks for the report.

netil avatar Jan 09 '20 00:01 netil

@netil yeah, your are right. If I rename data names to be "_30", "_20", "_10" - I receive expected ordering. Should be some type casting issue I assume.

creage avatar Jan 09 '20 06:01 creage

Internally, each data values are re-formatted as an object. (.convertColumnsToData() does this job)

// columns: [["30", 10], ["20", 20], ["10", 30]]
[{"30":1, "20":2, "10":1}]

The issue comes from that Object key with number, the order is not guaranteed as the assign order.

Ref: Does JavaScript Guarantee Object Property Order?

If you test defining an object with number keys, they will return as an ordered key object in every browsers (IE, Chrome, Edge, FF, etc.).

{"30":1, "20":2, "10":1}
// --> {10: 1, 20: 2, 30: 1}

So, to make orders to be maintained, it should add data names conversion adding a prefix like _. But before that I'm not sure if this addition(or the usage of data names in numbers) will generally beneficial in all circumstances.

netil avatar Jan 10 '20 09:01 netil

@netil Can't you read proper order from the columns entries? Like, finding index of a key from that array?

I can change my code so keys are not castable to Number, but I'm not sure if it is a good solution.

creage avatar Jan 10 '20 11:01 creage

@creage, looks simple, but doing that it needs to make whole refactoring on data conversion. You can use data.names option to handle this issue.

BTW, data.order option isn't for data entry's order. Is for stacking data or pie/donut's ordering.

netil avatar Jan 15 '20 08:01 netil

It seems this issue can be resolved if convertedData returned from convertColumnsToData has an explicitly ordered key list and convertDataToTargets uses it like this, dataKeys = data.keys || Object.keys(data[0] || {}). Is it good practice to add properties on array in javascript - Stack Overflow

watnab avatar Jun 17 '20 07:06 watnab