Forum Discussion
Sliding legend
Hi Anonymous,
Do you have an example of where you saw it, or what you are trying to achieve? Is it a particular custom visual? If so, which one? If we can get an idea of what you're aiming for then it might be possible to provide more targeted help.
Thanks,
Daniel
Hi dm-p ,
I meant this type of legend, as in this visual:
Legend in this visual slides to right, in case of large legend.
I wanted to use this type of legend in my custom visual.
Regards,
Yerkhan
- dm-p7 years agoSuper User
Hi Anonymous, and thanks for clarifying :)
Assuming you're using createLegend in powerbi-visuals-utils-chartutils to manage the creation of your legend, you need to set the isScrollable property to true.
If your legend exceeds the area the function reserves for it in the visual viewport, then you'll get the button to scroll to see the additional items.
Good luck!
Daniel
- Anonymous7 years agoNot applicable
- Anonymous7 years agoNot applicable
Could you please provide code of visual, where this legend is implemented?
I have some difficulties with adding it by github guide.
Regards,
Yerkhan
- dm-p7 years agoSuper User
I had a look at this, and the documentation of this library is quite out of date, and there's a number of quirks to getting it to work properly, which didn't help.
It took me about 3 hours to re-learn for the new v3 SDK and work out how to avoid breaking it, so I can understand why you're having trouble. I haven't looked at it in quite some time and it definitely used to work better. It's going to be fun to migrate some of my stuff to this version... :smileyfrustrated: I hear the team are working on improving the documentation... I really hope so.
To get this to work, I just created a new visual using pbiviz new and then removed all unnecessary code, but I'll paste my visual.ts below for you.
Things to bear in mind:
- Chartutils needs to be installed as a dependency:
npm i powerbi-visuals-utils-chartutils
- Critical references are the LegendData and LegendDataPoint interfaces, in terms of getting your data in there.
- Despire what the definition says, you need the following properties setting for each LegendDataPoint to ensure it renders without erroring:
- label
- color
- identity - this requires building a Selection ID and doesn't seem to work if you leave it null
- selected
- markerShape
- Invoking the drawLegend method will add a SVG element to the DOM. You will need to manage the sizing changes to your plot area after this is drawn.
- This can be done with the getMargins / getOrientation methods and adjusting your other elements accordingly.
- You can refer to the source of the violin plot for some examples of how this has been done, although it uses the older SDK so isn't subject to some of the stuff going on here, but I'd suggest keeping to the 1.2.0 code for reference; 1.3.0 gets a bit weird as it's manipulating the legend post-render.
- There's no error handling in the update method, so you'll need to ensure that you have a something in the Category field.
- I've added comments at the appropriare location in the imports to show where I've started to add stuff in.
Here's how it looks for a simple data set:
And, dragging the viewport across will cause the chart to scroll, e.g.:
Here's the code from my visual.ts:
"use strict"; import "core-js/stable"; import "./../style/visual.less"; import powerbi from "powerbi-visuals-api"; import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions; import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions; import IVisual = powerbi.extensibility.visual.IVisual; import EnumerateVisualObjectInstancesOptions = powerbi.EnumerateVisualObjectInstancesOptions; import VisualObjectInstance = powerbi.VisualObjectInstance; import DataView = powerbi.DataView; import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject; import { VisualSettings } from "./settings"; /** Added to support legend addition */ import IVisualHost = powerbi.extensibility.visual.IVisualHost; import { legendInterfaces, legend } from 'powerbi-visuals-utils-chartutils'; import createLegend = legend.createLegend; import ILegend = legendInterfaces.ILegend; import LegendDataPoint = legendInterfaces.LegendDataPoint; import LegendPosition = legendInterfaces.LegendPosition; import MarkerShape = legendInterfaces.MarkerShape; export class Visual implements IVisual { private target: HTMLElement; private settings: VisualSettings; private legend: ILegend; private host: IVisualHost; constructor(options: VisualConstructorOptions) { console.log('Visual constructor', options); this.target = options.element; /** Assign visual host */ this.host = options.host; /** Reserve element for legend */ this.legend = createLegend( this.target, false, null, true, /* scrollable */ LegendPosition.Top ); } public update(options: VisualUpdateOptions) { this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]); console.log('Visual update', options); /** THIS ASSUMES THAT YOUR DATA VIEW WORKS, SO THERE'S NO ERROR HANDLING. YOU WILL AT LEAST * NEED A VALUE IN THE CATEGORY DATA ROLE TO CONTINUE */ let categoryRole = options.dataViews[0].categorical.categories[0]; /** We're now going to create an array of LegendDataPoint objects to feed into our drawLegend * method below. * We're arbitrarily assigning a colour from the host's palette (theme) as it's required. You * might want to sub this out with your own from your view model */ let myLegendDataPoints: LegendDataPoint[] = categoryRole.values.map( (c, i) => ( { label: <string>c, color: this.host.colorPalette.getColor(<string>c).value, identity: this.host.createSelectionIdBuilder() .withCategory(categoryRole, i) .createSelectionId(), selected: false, markerShape: MarkerShape.circle } ) ); /** This actually draws the legend; note that although font settings aren't required, it will look * 'wrong' if they're not supplied */ this.legend.drawLegend( { title: 'Test Legend', fontSize: 10, dataPoints: myLegendDataPoints }, options.viewport ); } private static parseSettings(dataView: DataView): VisualSettings { return VisualSettings.parse(dataView) as VisualSettings; } /** * This function gets called for each of the objects defined in the capabilities files and allows you to select which of the * objects and properties you want to expose to the users in the property pane. * */ public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject { return VisualSettings.enumerateObjectInstances(this.settings || VisualSettings.getDefault(), options); } }Hopefully this helps in some way.
Good luck,
Daniel
- Chartutils needs to be installed as a dependency: