没有图例的图表区域的剑道图表高度

时间:2019-02-08 14:03:49

标签: kendo-ui-angular2 kendo-chart

我有一个内部有很多折线的折线图,图例显示在图表区域下方。问题在于,图例在垂直方向上会占用很多空间,而该空间是从图表的固定总高度中消耗掉的。在极端情况下,图表本身没有剩余空间。是否可以选择图表大小的固定大小,并在此之外添加图例的高度? 预先感谢!

2 个答案:

答案 0 :(得分:0)

您可以尝试弄乱这些值。这是一个示例:

<kendo-chart-legend 
    [labels]="{font:'8pt sans-serif'}" 
    [position]="'start" 
    [orientation]="'vertical'">
</kendo-chart-legend>

带有输入参数的完整示例。

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>

组件:

@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/

Full API here

答案 1 :(得分:0)

对于类似的情况,我只是为相关图表的图例设置了可见的false,并使用了新的图表小部件来仅显示图例。

  legend: {
    visible: false
  }

仅用于显示图例

$("#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
            }
        },
    });