简体   繁体   中英

How do you make a bar a different color in KendoUI bar chart?

I'm am replacing my dot net charting with KendoUI. I'm showing a Score Distribution chart. I want all of the bars to be the same color except the bar with the median score and the Legend. How do I color a single bar a unique color? How would I color the Legend this new color?

Below is my old dotnet charting bar chart and below that is the new KendoUI chart I'm trying to replace it with. I just need to get that coloring right and we'll be in business. Any help is appreciated.

在此输入图像描述

Update: I'm leaving the answer below this line intact in case there are those out there who are using an older version, but per a later comment , KendoUI now allows you to override styles for individual points in a series.


I don't believe you can, in the current version. That said, you can hack your way around the limitation.

You'll need to create two data series - one for your highlighted data, and one for everything else. Add both to you chart, and set them to stacked.

Here's a jsFiddle I put together to illustrate: http://jsfiddle.net/LyndsySimon/9VZdS/ . It depends on KendoUI's CDN, so if it breaks in the future I apologize.

Here is the Javascript for reference:

$(function() {
    var dataset = new Array(1,2,3,null,5,6);
    var highlighted = new Array(null,null,null,4,null,null);

    $('#chart').kendoChart({
        theme: 'metro',
        seriesDefaults: {
            type: 'column',
            stack: true
        },
        series: [
            {
                name: 'Not Highlighted',
                data: dataset,
                color: '#609'
            },
            {
                name: 'Highlighted',
                data: highlighted,
                color: '#f03'
            }
        ]
    })
});​

Starting with the 2012 Q2 release, bar series support binding the point color to a data item field.

This is done through the colorField option . The Binding to local data online example demonstrates it.

Both the Kendo UI and the legacy wrappers for ASP.NET MVC expose it as an option:

.Series(series =>
{
    series.Bar(model => model.Value, model => model.Color)
        .Name("United States");
})

All series overloads can be seen here .

You could hack the SVG generated by the system. I have supplied the chart with a model which contains the colour for each bar. eg:

public class Model
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public string Colour { get; set; }
    public decimal Score { get; set; }
}

Which is used as a series on the chart. The view then looks like:

@(Html.Telerik().Chart(Model)
    .Name("AverageScores")
    .Theme("Simple")
    .HtmlAttributes(new {style = "height: 500px"})
    .Series(series => series.Column(s => s.Score).Name("Name").Color("Blue"))
    .SeriesDefaults(sd => sd.Column().Labels(l =>
                                                 {
                                                     l.Visible(true);
                                                     l.Format("{0}%");
                                                 }))
    .Title("Mean Percentage Scores")
    .Legend(builder =>
                {
                    builder.Position(ChartLegendPosition.Bottom);
                    builder.Visible(false);
                })
    .CategoryAxis(ca => ca.Categories(x => x.Code))
    .Tooltip(builder =>
                 {
                     builder.Visible(true);
                     builder.Format("{0}%");
                     builder.Template("<#= dataItem.Name #><br/><#= value #>%");
                 })
    .ValueAxis(va => va.Numeric().Labels(a => a.Format("{0}%")).Min(0).Max(100)
    )
)

@section BelowTelerikScriptRegistrar
{
 <script type="text/javascript">


    function setAverageScoresColours() {
        var data = $('#AverageScores').data("tChart").options.series[0].dataItems;
        if (data != null) {
            for (var i = 0; i < data.length; i++) {
                var averageScore = data[i];
                $($($('div#AverageScores svg g')[i]).children('path')[0]).attr('fill', '#' + averageScore.Colour);
                $($($('div#AverageScores svg g')[i]).children('path')[0]).attr('stroke', '#' + averageScore.Colour);
            }
        }
    }

     $(document).ready(function () {
         setAverageScoresColours();
     })
 </script>
}

The section BelowTelerikScriptRegistrar must happen after the Html.Telerik().ScriptRegistrar() is called.

This will work in Chrome, Firefox and IE10. I have noticed there is a problem with multiple chart and the timings around the generation of the SVG. Unfortunately you might have to wrap setAverageScoresColours() in a setTimeout function to ensure the SVG has been generated, but it seems to work with just one chart.

A bit hacky, but easier than managing lots of series.

And for KendoUI (which I have edited for...):

<div class="chart-wrapper">
    <div id="chart"></div>
</div>

 <script>
 function createChart() {
     $("#chart").kendoChart({
         theme: $(document).data("kendoSkin") || "default",
         title: {
             text: "Internet Users"
         },
         legend: {
             position: "bottom"
         },
         seriesDefaults: {
             type: "column"
         },
         series: [{
             name: "World",
             data: [15.7, 16.7, 20, 23.5, 26.6]
         }],
         valueAxis: {
             labels: {
                 format: "{0}%"
             }
         },
         categoryAxis: {
             categories: [2005, 2006, 2007, 2008, 2009]
         },
         tooltip: {
             visible: true,
             format: "{0}%"
         }
     });
 }

 $(document).ready(function () {
     setTimeout(function () {
         // Initialize the chart with a delay to make sure
         // the initial animation is visible
         createChart();
         $($($('div#chart svg g')[0]).children('path')[0]).attr('fill', '#123');
         $($($('div#chart svg g')[1]).children('path')[0]).attr('fill', '#321');
         $($($('div#chart svg g')[2]).children('path')[0]).attr('fill', '#213');
         $($($('div#chart svg g')[3]).children('path')[0]).attr('fill', '#312');
         $($($('div#chart svg g')[4]).children('path')[0]).attr('fill', '#132');
     }, 400);
 });
</script>

Another way you can do it at runtime is using function which returns color.

API reference

Here is an example code:

<div id="chart"></div>
<script>
$("#chart").kendoChart({
  series: [{
    data: [1, 2],
    color: function(point) {
      if (point.value > 1) {
        return "red";
      }

      // use the default series theme color
    }
  }]
});
</script>

This is not currently possible with current KendoUI version.

It's on their todo-list.

http://www.kendoui.com/forums/dataviz/chart/change-bar-column-color-for-each-point.aspx

There can be a kind of workaround, as said in the thread I've put here, it would be to describe a series for each color you need. It looks very inefficient to me, but it's currently the only way to do it. If you have only 1 chart, you could do it. Else, wait for a new version of KendoUI with this feature.

Telerik have recently released a Kendo UI Data Vis Theme Roller

http://demos.kendoui.com/themebuilder/dataviz.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM