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

Proposal: auto polygon arrangement in radar chart

Open qkreltms opened this issue 4 years ago • 1 comments

Description

Imagine that we have two polygons in radar chart which are blue and red. Blue is bigger than red on Fig 1. You can clearly identify two polygons.

    data: {
      columns: [
        ["blue", ...props.blueData],
        ["red", ...props.redData],
      ], 
    }

Now let blue becomes smaller than red. Blue is indistinguishable on Fig 2.

    data: {
      columns: [
        ["blue", ...props.blueData.map(d => Math.abs(d - 20))],
        ["red", ...props.redData],
      ], 
    }

In this case, what if we change node stacking of each one? Blue is now distinguishable on Fig 3. It would be good if auto polygon arrangement function is implemented in billboardjs by default rather than implements this function manually by users.

Usage

radar.autoArrangement= false | "asc" | "desc"

Fig 1 Fig1 Fig 2 Fig2 Fig 3 Fig3

qkreltms avatar Jul 24 '20 02:07 qkreltms

@qkreltms, the current stacking order is based on the order of data bound.

So, if you want to control shape orders, make sure to put in descendant orders.

// in this case, 'data1' will be positioned behind the 'data2' according its data bound order.
columns: [
    ["data1", 130],
    ["data2", 130],
]

Determining which shapes should stay behind or not, there're factors to be considered. Based on your example is quite easy, because the blue is more smaller than the red, but what if one of the edges is greater than the red and the rest smaller? (or imagine in the case of 2 edges)

You can implement by your own criteria, sorting the data order for now.

The below example will sort in descending order base on the data total sum. (Note that total sum doesn't mean always greater than the other shape)

function sortDesc(arr) {
	const sum = v => v.reduce((a, c) => (isNaN(a) ? 0 : a) + c);

	return arr.sort((a, b) => sum(b) - sum(a));
}

var data = [
	["data2", 130, 100, 30, 200, 80],
	["data1", 330, 350, 200, 380, 150],
];

var chart = bb.generate({
  data: {
    x: "x",
    columns: [
		["x", "Data A", "Data B", "Data C", "Data D", "Data E"],
               // will be sorted as : 'data1' -> 'data2'
		...sortDesc(data)
    ],
	type: "radar"
  }
});

netil avatar Jul 24 '20 08:07 netil