javascriptangulartypescriptkendo-ui-angular2kendo-chart

Top position for Kendo chart series item label


I have Kendo column chart with multiple series per category.

I'm trying to put Kendo chart series item labels on top regardless of value. By default, it's put in the end of chart item. So for positive values it's on top of column and for negatives it's at the bottom.

Overlapping label and note

app.component.html

<kendo-chart>
  <kendo-chart-category-axis>
    <kendo-chart-category-axis-item [labels]="{ margin: { top: 10 } }">
    </kendo-chart-category-axis-item>
  </kendo-chart-category-axis>

  <kendo-chart-value-axis>
    <kendo-chart-value-axis-item>
    </kendo-chart-value-axis-item>
  </kendo-chart-value-axis>

  <kendo-chart-series>
    <kendo-chart-series-item *ngFor="let groupedResult of groupedData"
                            [data]="groupedResult.items"
                            field="income"
                            type="column"
                            categoryField="clientName"
                            noteTextField="income">
      <kendo-chart-series-item-labels format="C0">
      </kendo-chart-series-item-labels>
      <kendo-chart-series-item-notes position="bottom"
                                     [icon]="{ visible: false }"
                                     [line]="{ width: 0 }"
                                     [label]="noteLabel">
      </kendo-chart-series-item-notes>
    </kendo-chart-series-item>
  </kendo-chart-series>
</kendo-chart>

app.component.ts

import { Component, OnInit } from '@angular/core';
import * as _ from 'lodash';

export type TrendItem = {
  clientName: string;
  year: number;
  period: number;
  income: number;
};

export type GroupedTrendItem = {
  value: { year: number; period: number };
  items: TrendItem[];
};

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
})
export class AppComponent implements OnInit {
  public trendItems: TrendItem[] = [
    {
      clientName: 'Client1',
      year: 2020,
      period: 3,
      income: -35,
    },
    {
      clientName: 'Client1',
      year: 2020,
      period: 4,
      income: 40,
    },
    {
      clientName: 'Client2',
      year: 2020,
      period: 1,
      income: -15,
    },
    {
      clientName: 'Client2',
      year: 2020,
      period: 2,
      income: 20,
    },
    {
      clientName: 'Client2',
      year: 2020,
      period: 3,
      income: 15,
    },
    {
      clientName: 'Client3',
      year: 2020,
      period: 2,
      income: 50,
    },
    {
      clientName: 'Client3',
      year: 2020,
      period: 3,
      income: -35,
    },
    {
      clientName: 'Client3',
      year: 2020,
      period: 4,
      income: 20,
    },
  ];

  public noteLabel = {
    color: 'black',
    content: e => `Q${e.dataItem.period} ${e.dataItem.year}`,
    font: '12px Arial',
    margin: -30,
  };

  private getGroupedTrends() {
    const groupedTrendItems = this.trendItems.reduce((acc, trendItem) => {
      let element = acc.find(el => el.value.year === trendItem.year
        && el.value.period === trendItem.period
      );

      if (element) {
        element.items.push(trendItem);
      } else {
        acc.push({
          value: { year: trendItem.year, period: trendItem.period },
          items: [trendItem],
        });
      }
      return acc;
    }, [] as GroupedTrendItem[]);

    return _.sortBy(groupedTrendItems, [
      item => item.value.year,
      item => item.value.period,
    ]);
  }

  public groupedData = this.getGroupedTrends();

  public ngOnInit() {
    console.log(this.groupedData);
  }
}

You can try this code here.

Unfortunately, labels don't have available 'top' option for SeriesLabelsPosition component when working with column chart (TBH I don't know why). If I don't need to display period, I will be using SeriesNotesComponent like I do now for periods. They can have position="top" assigned without any problem.


So, the question is how to get labels displayed on top of column regardless of value.


Solution

  • This works

    <kendo-chart-series-item-labels format="C0" position="top" [margin]="-25">
    </kendo-chart-series-item-labels>
    

    Stackblitz: https://stackblitz.com/edit/angular-hsczmx-swsaon?file=app/app.component.html