arun kumar
arun kumar

Reputation: 49

Kendo Angular Bar chart customization on applying gradient color

enter image description hereiam new to Kendo UI angular, i have to customize a bar chart, where every bar will have multiple color gradient. is it possible to attain in kendo? i have my bar chart developed in fusion but iam finding it little difficult to acheive the same with kendo.

have attached an image of what i need to achieve and also what my code in kendo is.

my code in kendo

<kendo-chart style="height: 317px;">
    <kendo-chart-axis-defaults [majorGridLines]="{ visible : false}">
      </kendo-chart-axis-defaults>
      <kendo-chart-series-defaults type="bar">
          <kendo-chart-series-defaults-labels format="">
          </kendo-chart-series-defaults-labels>
      </kendo-chart-series-defaults>
    <kendo-chart-category-axis >
        <kendo-chart-category-axis-item [categories]="['jan','feb','mar','apr','may','jun','aug','set','oct','nov','dec']">
        </kendo-chart-category-axis-item>
    </kendo-chart-category-axis>
  <kendo-chart-series>                  
      <kendo-chart-value-axis>
          <kendo-chart-value-axis-item [line]="{visible:false}" labels="false">
          </kendo-chart-value-axis-item>
      </kendo-chart-value-axis>
    <kendo-chart-series-item 
      type="column"
      [color]="pointColor"
      [gap]="10"
      [stack]="true" 
      [data]="['1000','0','200','2000','1500','1000','0','200','2000','1500','3500','25']"
      >
      <kendo-chart-series-item-labels [content]="labelContent" rotation="90" [position]="end" >
        </kendo-chart-series-item-labels>
    </kendo-chart-series-item>
  </kendo-chart-series>
</kendo-chart>

Upvotes: 1

Views: 2431

Answers (3)

flyer
flyer

Reputation: 1424

I found that they expose hooks that allows you to control how each bar is rendered. Using the seriesDefaults property on kendo-chart, you can provide your own visual() method. Steps:

  1. In your template, bind to seriesDefaults:
<kendo-chart [seriesDefaults]="seriesDefaults"></kendo-chart>
  1. In your component, provide a custom visual method on seriesDefaults:
    seriesDefaults: SeriesDefaults = {
            type: 'column',
            visual: (e: SeriesVisualArgs) => createColumn(e.rect, e.options.color, e.dataItem),
        };
  1. The custom method could look something like this. Optionally I added a text item above each bar to show the dataItem value (it's rough, I'm making assumptions about it's x/y position):
export function createColumn(rect: geometry.Rect, color: string, dataItem: number): Group {
        const gradient = new LinearGradient(<GradientOptions>{
            stops: [new GradientStop(0, color, 0.7), new GradientStop(0.4, color, 1)],
        });
        gradient.start([0.5, 0]);
        gradient.end([0.5, 1]);
    
        // Turn the rect into a path and reference the gradient
        const path = Path.fromRect(rect, <ShapeOptions>{
            fill: gradient,
            stroke: {
                color: '#777',
                width: 1,
            },
        });
    
        // Add the dataItem value above the bar
        const position = rect.topLeft();
        position.y -= 13;
        position.x += (rect.width() / 2) - 10;
        const text = new Text(dataItem + '', position);
    
        const group = new Group();
        group.append(path);
        group.append(text);
        return group;
    }
    ```

[![Results][1]][1]


  [1]: https://i.sstatic.net/wVOmQ.png

Upvotes: 0

Marissa Fernandes
Marissa Fernandes

Reputation: 781

Looking at your chart I feel like it can be achieved by a 100% stacked column chart you can get the data for both colored and grayed out portions. Then use a label property which can be displayed and with rotation.

<script>
$("#chart").kendoChart({
  series: [ {
    labels: {
      visible: true,
      position: "outsideEnd",
      rotation: 270 
    },
    data: [1, 2, 3]
  }]
});
</script>

Tried to get a similar look for the bar chart using radial gradient and 100% stacked bars

import { Component } from '@angular/core';
import { Surface, Path, Text, Group, Layout, LinearGradient, RadialGradient, GradientOptions, ShapeOptions } from '@progress/kendo-drawing';
import { Arc as DrawingArc, GradientStop } from '@progress/kendo-drawing';
import { Arc, Rect, ArcOptions } from '@progress/kendo-drawing/geometry';
function createColumn(rect, color) {
            const origin = rect.origin;
            const bottomRight = rect.bottomRight();

            const radialgradient = new RadialGradient(<GradientOptions>{
               center:[0.5, 0],
                stops: [new GradientStop(0.5, color, 1),
                        new GradientStop(1, "#98FB98", 1)]
            });

            const path = Path.fromRect(rect, <ShapeOptions>{
                    fill: radialgradient,
                    stroke: {
                        color: color,
                        width: 1
                    }
                });

              const path1 = Path.fromRect(rect, <ShapeOptions>{
                    fill: {color: color},
                    stroke: {
                        color: color,
                        width: 1
                    }
                });

            const group = new Group();
            if(color == "#eee"){
                group.append(path1);
            }
            else{
                group.append(path);
            }

            return group;
        }

@Component({
  selector: 'my-app',
  template: `
    <kendo-chart [seriesDefaults]="chartConfig.seriesDefaults" >
      <kendo-chart-title text="Units sold"></kendo-chart-title>
      <kendo-chart-category-axis>
          <kendo-chart-category-axis-item [categories]="['Q1', 'Q2', 'Q3', 'Q4']">
          </kendo-chart-category-axis-item>
      </kendo-chart-category-axis>
      <kendo-chart-series>
        <kendo-chart-series-item type="column" [stack]="{ type: '100%' }" [gap]="2" [spacing]=".25" [data]="[100, 120, 250, 345]" color="#008852">
        </kendo-chart-series-item>
         <kendo-chart-series-item type="column" [data]="[400, 380, 250, 155]" color="#eee">
        </kendo-chart-series-item>
      </kendo-chart-series>
    </kendo-chart>
  `
})
export class AppComponent {
public chartConfig = {
      seriesDefaults: {
          visual: function (e) {
              return createColumn(e.rect, e.options.color);
          }
      }
  };

}

Upvotes: 0

Marissa Fernandes
Marissa Fernandes

Reputation: 781

For a gradient effect you can use the series property overlay.

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <kendo-chart>
      <kendo-chart-title text="Units sold"></kendo-chart-title>
      <kendo-chart-category-axis>
          <kendo-chart-category-axis-item [categories]="['Q1', 'Q2', 'Q3', 'Q4']">
          </kendo-chart-category-axis-item>
      </kendo-chart-category-axis>
      <kendo-chart-series>
        <kendo-chart-series-item type="bar" [gap]="2" [spacing]=".25" [data]="[100, 123, 234, 343]" [overlay]="{gradient: 'roundedBevel'}">
        </kendo-chart-series-item>
        <kendo-chart-series-item type="bar" [data]="[120, 67, 231, 196]" [overlay]="{gradient: 'glass'}" >
        </kendo-chart-series-item>
        <kendo-chart-series-item type="bar" [data]="[45, 124, 189, 143]" [overlay]="{gradient: 'none'}">
        </kendo-chart-series-item>
        <kendo-chart-series-item type="bar" [data]="[87, 154, 210, 215]" [overlay]="{gradient: 'sharpBevel'}">
        </kendo-chart-series-item>
      </kendo-chart-series>
    </kendo-chart>
  `
})
export class AppComponent {}

Also came across this demo, for creating custom linear gradients. Please refer to code below I have created a linear gradient column chart as an example.

import { Component } from '@angular/core';
import { Surface, Path, Text, Group, Layout, LinearGradient, GradientOptions, ShapeOptions } from '@progress/kendo-drawing';
import { Arc as DrawingArc, GradientStop } from '@progress/kendo-drawing';
import { Arc, Rect, ArcOptions } from '@progress/kendo-drawing/geometry';
function createColumn(rect, color) {
            const origin = rect.origin;
            const bottomRight = rect.bottomRight();
            const gradient = new LinearGradient(<GradientOptions>{
                stops: [new GradientStop(0, "#98FB98", 1),
                        new GradientStop(0.5, color, 1)]
            });

              const path = Path.fromRect(rect, <ShapeOptions>{
                    fill: gradient,
                    stroke: {
                        color: color,
                        width: 1
                    }
                });

            const group = new Group();
            group.append(path);
            return group;
        }

@Component({
  selector: 'my-app',
  template: `
    <kendo-chart [seriesDefaults]="chartConfig.seriesDefaults" >
      <kendo-chart-title text="Units sold"></kendo-chart-title>
      <kendo-chart-category-axis>
          <kendo-chart-category-axis-item [categories]="['Q1', 'Q2', 'Q3', 'Q4']">
          </kendo-chart-category-axis-item>
      </kendo-chart-category-axis>
      <kendo-chart-series>
        <kendo-chart-series-item type="bar" [gap]="2" [spacing]=".25" [data]="[100, 123, 234, 343]" color="#008852">
        </kendo-chart-series-item>
      </kendo-chart-series>
    </kendo-chart>
  `
})
export class AppComponent {
public chartConfig = {
      seriesDefaults: {
          type: 'column',
          visual: function (e) {
              return createColumn(e.rect, e.options.color);
          }
      }
  };

}

Upvotes: 2

Related Questions