I have a line chart with many lines inside, the legend is displayed below the chart area. The problem is that the legend takes a lot of space vertically, and this space is consumed from the fix total height of the chart. In extreme cases, there is no space left for the chart itself. Is there an option to have a fix size for the chart area, and add the legend's height in addition to this? Thanks in advance!
Asked
Active
Viewed 2,015 times
-1
-
Please let me know if my answer helped you. If it did, please mark it as the answer. – Joel Feb 11 '19 at 09:50
-
Are you using kendo for jquery? MVC? Angular??? – CMartins Feb 14 '19 at 15:10
-
I use the Angular one – Tamás Mészáros Mar 22 '19 at 07:48
2 Answers
0
You can try to mess around with these values. Here's an example:
<kendo-chart-legend
[labels]="{font:'8pt sans-serif'}"
[position]="'start"
[orientation]="'vertical'">
</kendo-chart-legend>
Full example with Input Params.
HTML:
<kendo-chart (render)="onRender($event)">
<kendo-chart-legend
[labels]="{font:'12pt sans-serif'}"
[position]="legendPosition"
[orientation]="legendOrientation">
</kendo-chart-legend>
<kendo-chart-title
[text]="titleDescription"
font="12pt sans-serif"
[align]="titleAlign">
</kendo-chart-title>
<kendo-chart-tooltip [shared]="sharedTooltip" [format]="formatTooltip"></kendo-chart-tooltip>
<kendo-chart-category-axis>
<kendo-chart-category-axis-item
name="categoryAxis"
[labels]="{font:'10pt sans-serif'}"
[visible]="labelStep !== 0">
<kendo-chart-category-axis-item-labels [step]="labelStep" [content]="labelContentString" [rotation]="labelRotation"></kendo-chart-category-axis-item-labels>
</kendo-chart-category-axis-item>
</kendo-chart-category-axis>
<kendo-chart-value-axis>
<kendo-chart-value-axis-item
name="valueAxis"
[plotBands]="plotBands"
[labels]="{font:'12pt sans-serif'}">
<kendo-chart-value-axis-item-labels [content]="labelContentString"></kendo-chart-value-axis-item-labels>
</kendo-chart-value-axis-item>
</kendo-chart-value-axis>
<kendo-chart-series>
<ng-container *ngIf="groupByField">
<kendo-chart-series-item *ngFor="let item of series"
[type]="type"
[data]="item.items"
[name]="item.value"
[markers]="{visible: useMarkers}"
field="value"
categoryField="label">
</kendo-chart-series-item>
</ng-container>
<ng-container *ngIf="!groupByField">
<kendo-chart-series-item
[type]="type"
[data]="series"
[markers]="{visible: useMarkers}"
field="value"
categoryField="label">
</kendo-chart-series-item>
</ng-container>
</kendo-chart-series>
</kendo-chart>
Component:
@Input() public data: PentahoResponse;
@Input() public type: string;
@Input() public groupByField: string;
@Input() public labelField: string;
@Input() public valueField: string;
@Input() public excludeValues: Array<{ field: string, value: string }> = [];
@Input() public titleDescription: string = ""; // text (disabled if left empty)
@Input() public titleAlign: string = "start"; // start middle end
@Input() public legendPosition: string; // top bottom left right
@Input() public legendOrientation: string; // horizontal vertical
@Input() public formatTooltip: string = "{0}"; // {0} <-- value
@Input() public sharedTooltip: boolean = false; // false true
@Input() public useMarkers: boolean = true; // false true
@Input() public preferredLabelAmount: number = 15;
@Input() public labelRotation: number;
@Input() public lines: Array<{ value: number, color: string, opacity?: number }>;
private series: any[] = [];
private labelStep: number = 1;
constructor(
@Inject(AppService) private readonly appService: AppService
) { }
public onRender(args) {
if (this.lines && this.type === "line") {
const chart = args.sender.instance; // Remove ".instance" when upgraded
// get the axes
const valueAxis = chart.findAxisByName("valueAxis");
const categoryAxis = chart.findAxisByName("categoryAxis");
// get the coordinates of the entire category axis range
const range = categoryAxis.range();
const categorySlot = categoryAxis.slot(range.min, range.max);
const group = new Group();
this.lines.forEach((plotLine) => {
// get the coordinates of the value at which the plot band will be rendered
const valueSlot = valueAxis.slot(plotLine.value);
// draw the plot band based on the found coordinates
const line = new Path({
stroke: {
color: plotLine.color,
width: 3,
opacity: plotLine.opacity !== undefined ? plotLine.opacity : 1
}
}).moveTo(valueSlot.origin)
.lineTo(categorySlot.topRight().x, valueSlot.origin.y);
group.append(line);
});
// Draw on the Chart surface to overlay the series
chart.surface.draw(group);
}
}
private getData() {
const metadata = this.data.metadata;
let data = this.data.resultset;
this.excludeValues.forEach((exclude) => {
const fieldIndex: number = _.findIndex(metadata, (x) => x.colName === exclude.field);
if (fieldIndex !== -1) {
data = _.filter(data, (x) => x[fieldIndex] !== exclude.value);
}
});
const labelIndex = _.findIndex(metadata, (x) => x.colName === this.labelField);
const valueIndex = _.findIndex(metadata, (x) => x.colName === this.valueField);
const groupByFieldIndex = _.findIndex(metadata, (x) => x.colName === this.groupByField);
data.forEach((row) => {
this.series.push({
groupBy: groupByFieldIndex !== -1 ? row[groupByFieldIndex] : row[labelIndex],
value: row[valueIndex],
label: row[labelIndex],
groupByKey: groupByFieldIndex !== -1 ? row[groupByFieldIndex] : row[labelIndex],
valueKey: row[valueIndex],
labelKey: row[labelIndex]
});
});
this.series = this.groupByField !== undefined ? groupBy(this.series, [{ field: "groupBy" }]) : this.series;
}
private labelContentString = (e: any) => {
if (e.value instanceof Date) {
return moment(e.value).format("L LT");
} else if (e.value instanceof String) {
return this.appService.translate(e.value);
}
return e.value;
}
public ngOnInit() {
this.getData();
if (this.preferredLabelAmount > 0) {
let maxTotalItems = 0;
if (this.groupByField !== undefined) {
this.series.forEach((serie: GroupResult) => {
if (maxTotalItems < serie.items.length) {
maxTotalItems = serie.items.length;
}
});
} else {
maxTotalItems = this.series.length;
}
this.labelStep = Math.round(maxTotalItems / this.preferredLabelAmount);
} else if (this.preferredLabelAmount === 0) {
this.labelStep = 0;
}
}
https://www.telerik.com/kendo-angular-ui/components/charts/api/Legend/
https://www.telerik.com/kendo-angular-ui/components/charts/api/LegendLabels/
https://www.telerik.com/kendo-angular-ui/components/charts/api/LegendItem/
https://www.telerik.com/kendo-angular-ui/components/charts/api/LegendMarkers/

Joel
- 5,732
- 4
- 37
- 65
-
Sorry, this didn't help. I can spare some space with decreasing the font, but it is not enough. Sometimes I have ~ 100 lines on the chart, in such cases, the legend is ~400px (I know, you can't even really distinguish the lines, but that's a different issue). In other cases, only 1 or 2. So finally, I solved this by traversing the SVG's DOM, recognizing the items in the legend, and checking their positions. Based on this, I can calculate the height required for the legend, and increase the height of the chart with this. – Tamás Mészáros Feb 14 '19 at 08:15
0
For a similar situation I just set the visible false for the legend of the chart in question and used a new chart widget to just display a legend.
legend: {
visible: false
}
For just displaying a legend
$("#legendChart").kendoChart({
legend: {
position: "top",
labels: {
padding: {
left: paddingLeftLegendLabel
}
}
},
series: [
{ name: LowName },
{ name: MediumName },
{ name: HighName },
],
seriesColors: ['#DCD267', '#DC8C67', '#DC6967'],
chartArea: {
height: 35
},
axisDefaults: {
visible: false,
majorGridLines: {
visible: false
}
},
});

Marissa Fernandes
- 761
- 4
- 8
-
But how do you know how much height do you need for the legend? – Tamás Mészáros Mar 22 '19 at 07:50
-