Forum Discussion

merinsverghese's avatar
merinsverghese
Cloud Apps
08-09-2024
Solved

How to apply color to 'Break by' legends based on another column.

Currently I have around 40 items in 'Break By' legend. I want to apply color based on their category (4 category - 4 color)

  • Hey merinsverghese ,

    There are a few ways to do this (like sending additional jaql queries in the widget script, but I think the more simple and efficient way is below (despite feeling a bit more hacky):

    In the datamodel, you'll need to create a new column indicating the grouping "<group>_<item>" to use as the break_by:

    Then we can create 'colorConfiguration' based on the text for each value before the '_'. We'll assign each unique category a color based on the dashboard pallette (colors) and then use similar logic to run through the categories.

    Updated widget script:

     

    function onlyUnique(value, index, array) {
    	return array.indexOf(value) === index
    }
    
    
    widget.on('processresult', (w, args) => {
    	let colourGroups = args.result.series.map((s) => { return s.name.split('_')[0] })
    	let uniqueColourGroups = colourGroups.filter(onlyUnique)
    	let colors = widget.dashboard.style.$$colors
    
    	let colorConfiguration = uniqueColourGroups.map((v, i) => {
    		return {
    			category: v,
    			groupColor: colors[i]
    		}
    	})
    
    	let l = args.result.series.length
    	let l2 = colorConfiguration.length
    	for (let i = 0; i < l; i++) {
    		let bar = args.result.series[i]
    		for (let j = 0; j < l2; j++) {
    			let colorConfigRule = colorConfiguration[j]
    			if (colorConfigRule.category === bar.name.split('_')[0]) {
    				bar.color = colorConfigRule.groupColor
    				bar.name = bar.name.split('_')[1]
    				bar.data.forEach((d) => {
    					d.color = colorConfigRule.groupColor
    					d.borderColor = 'black'
    					d.borderWidth = 1
    				})
    			}
    		}
    	}
    })
    

     

     Which results in:

    A few things:

    • this will break if you don't have a '_' in every value.
    • this will probably break if you have nothing after or before the '_'
    • you probably want to test different scenarios around this, as there is a bit going on here and I can't guarantee this will work in 100% of cases.

    If you need any additional customization - feel free to take us up on our free 30-minute consult: https://www.rapidbi.com.au/sisense-add-ons/Services/Free-30-Minute-Sisense-Consultation/

    Let me know how you go?

    Thanks,

    Daniel

    RAPID BI

    [email protected]

    RAPID BI - Sisense Professional Services | Implementations | Custom Add-ons

     

4 Replies

  • Hi merinsverghese ,

    You could do something like this on a widget script:

    let colorConfiguration = [
    	{ 
    		category: 'a',
    		seriesNames: ['Bikes', 'Body Armor', 'Build Kits', 'Cables &amp; Housing'],
    		groupColor: 'blue'
    	},
    	{ 
    		category: 'b',
    		seriesNames: ['Frames', 'Helmets', 'Wheels &amp; Wheelsets'],
    		groupColor: 'red'
    	}
    ]
    
    widget.on('processresult', (w, args) => {
      let l = args.result.series.length
      let l2 = colorConfiguration.length
      for (let i = 0; i < l; i++) {
        let bar = args.result.series[i]
    	
    	for (let j = 0; j < l2; j++) {
    	  let colorConfigRule = colorConfiguration[j]
    	  if (colorConfigRule.seriesNames.includes(bar.name)) { 
    	    bar.color = colorConfigRule.groupColor
    		bar.data.forEach((d) => { 
    			d.color = colorConfigRule.groupColor
    			d.borderColor = 'black'
    			d.borderWidth = 1
    		})
    	  }
    	}
    	
      }
     
    })

    You can add to the colorConfiguration in the script to add different groups of breakby categories to color by.

    Additionally, youi can set different colors for the column bar borders by adjusting borderColor lower in the script.

    This results in:

    Let me know how you go?

    Thanks,

    Daniel

    RAPID BI

    [email protected]

    RAPID BI - Sisense Professional Services | Implementations | Custom Add-ons

    • merinsverghese's avatar
      merinsverghese
      Cloud Apps

      Hi Daniel,

      Thank you for the solution, I tried out the same. In my case the items in the break by (field - 'Item') will increase day by day. So I need a dynamic solution, that will pick the corresponding category from the available field('category') in the data model. 

      categoryItem
      a1
      b2
      b3
      a4
      c5
      c6
      c7

       

      Regards,

      Merin

  • Hey merinsverghese ,

    There are a few ways to do this (like sending additional jaql queries in the widget script, but I think the more simple and efficient way is below (despite feeling a bit more hacky):

    In the datamodel, you'll need to create a new column indicating the grouping "<group>_<item>" to use as the break_by:

    Then we can create 'colorConfiguration' based on the text for each value before the '_'. We'll assign each unique category a color based on the dashboard pallette (colors) and then use similar logic to run through the categories.

    Updated widget script:

     

    function onlyUnique(value, index, array) {
    	return array.indexOf(value) === index
    }
    
    
    widget.on('processresult', (w, args) => {
    	let colourGroups = args.result.series.map((s) => { return s.name.split('_')[0] })
    	let uniqueColourGroups = colourGroups.filter(onlyUnique)
    	let colors = widget.dashboard.style.$$colors
    
    	let colorConfiguration = uniqueColourGroups.map((v, i) => {
    		return {
    			category: v,
    			groupColor: colors[i]
    		}
    	})
    
    	let l = args.result.series.length
    	let l2 = colorConfiguration.length
    	for (let i = 0; i < l; i++) {
    		let bar = args.result.series[i]
    		for (let j = 0; j < l2; j++) {
    			let colorConfigRule = colorConfiguration[j]
    			if (colorConfigRule.category === bar.name.split('_')[0]) {
    				bar.color = colorConfigRule.groupColor
    				bar.name = bar.name.split('_')[1]
    				bar.data.forEach((d) => {
    					d.color = colorConfigRule.groupColor
    					d.borderColor = 'black'
    					d.borderWidth = 1
    				})
    			}
    		}
    	}
    })
    

     

     Which results in:

    A few things:

    • this will break if you don't have a '_' in every value.
    • this will probably break if you have nothing after or before the '_'
    • you probably want to test different scenarios around this, as there is a bit going on here and I can't guarantee this will work in 100% of cases.

    If you need any additional customization - feel free to take us up on our free 30-minute consult: https://www.rapidbi.com.au/sisense-add-ons/Services/Free-30-Minute-Sisense-Consultation/

    Let me know how you go?

    Thanks,

    Daniel

    RAPID BI

    [email protected]

    RAPID BI - Sisense Professional Services | Implementations | Custom Add-ons

     

    • merinsverghese's avatar
      merinsverghese
      Cloud Apps

      This solution worked for me. Thankyou Daniel. 

      Regards,

      Merin