问题
I am using Live Charts WPF to draw some charts. To make each column bar of different color I added multiple series, but it doesn't show x-axis
labels of all series. Why?
senderChart.Series = new SeriesCollection();
int i = 0;
var ax = new Axis
{
Separator = new LiveCharts.Wpf.Separator()
{
Step = 1
},
Labels = dateValues,
ShowLabels = true
};
senderChart.AxisX.Add(ax);
foreach (var val in dataValues)
{
senderChart.Series.Add(new ColumnSeries
{
DataLabels = true,
Title = dateValues[i],
Values = new ChartValues<double>{val},
});
i++;
}
I also have tried almost every different way of assigning series to chart but still got same result.
回答1:
You have 20 series, but each of them only has a single data point, that is why you only get one label. Using only a single series would be closer to LiveCharts’ intended use. You can then control the bar color by introducing a mapper (further info).
Here is an example:
//create the mapper
var dapperMapper = new CartesianMapper<double>()
//the data point will be displayed at the position of its index on the X axis
.X((value, index) => index)
//the data point will have a Y value of its value (your double) aka the column height
.Y((value) => value)
//pass any Func to determine the fill color according to value and index
//in this case, all columns over 3 height will be pink
//in your case, you want this to depend on the index
.Fill((value, index) => (value > 3.0 ? Brushes.HotPink : Brushes.YellowGreen));
//assign the mapper globally (!)
LiveCharts.Charting.For<double>(dapperMapper, SeriesOrientation.Horizontal);
With that, you can use a single series with one value per month. You could have your Fill Func
be something like this, where it cycles through 12 colors.
Here is a full example with names close to yours:
public partial class MainWindow : Window
{
public SeriesCollection senderChart { get; set; }
public double[] dataValues = { 1, 7, 4, 8, 3, 12, 4, 3, 2, 21, 4, 2, 7, 3, 23, 34, 5, 47, 2, 3, 45, 58, 3, 4 };
public string[] dateValues = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
public MainWindow()
{
var doubleMapperWithMonthColors = new LiveCharts.Configurations.CartesianMapper<double>()
.X((value, index) => index)
.Y((value) => value)
.Fill((v, i) =>
{
switch (i % 12)
{
case 0: return Brushes.LightBlue; //january
case 1: return Brushes.LightCoral; //february
case 2: return Brushes.PaleGoldenrod; //march
case 3: return Brushes.OrangeRed; //april
case 4: return Brushes.BlueViolet; //may
case 5: return Brushes.Chocolate; //june
case 6: return Brushes.PaleVioletRed; //july
case 7: return Brushes.CornflowerBlue; //august
case 8: return Brushes.Orchid; //september
case 9: return Brushes.Thistle; //october
case 10: return Brushes.BlanchedAlmond; //november
case 11: return Brushes.YellowGreen; //december
default: return Brushes.Red;
}
});
LiveCharts.Charting.For<double>(doubleMapperWithMonthColors, SeriesOrientation.Horizontal);
senderChart = new SeriesCollection();
var columnSeries = new ColumnSeries() { Values = new ChartValues<double>(), DataLabels = true, Title = "Appointments" };
var labels = this.dateValues;
foreach (var val in dataValues)
{
columnSeries.Values.Add(val);
}
this.senderChart.Add(columnSeries);
DataContext = this;
}
}
XAML:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
Title="MainWindow" Height="400" Width="900">
<lvc:CartesianChart Series="{Binding senderChart}" Margin="48, 48, 48, 24">
<lvc:CartesianChart.AxisX>
<lvc:Axis Labels="{Binding Labels}">
<lvc:Axis.Separator>
<lvc:Separator Step="1" Stroke="{x:Null}"/>
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisX>
</lvc:CartesianChart>
</Window>
Result:
回答2:
Call this method to assign Chart color assignment globally. Call it before your chart load method or in constructor. It will work 100% .
public static void ChartColorAssignment()
{
CartesianMapper<double> _dapperMapper = new CartesianMapper<double>()
.X((value, index) => index)
.Y((value) => value)
.Fill((value, index) => (value > 3.0 ? Brushes.DodgerBlue : Brushes.Yellow));
Charting.For<double>(_dapperMapper, SeriesOrientation.Horizontal);
var doubleMapperWithMonthColors = new CartesianMapper<double>()
.X((value, index) => index)
.Y((value) => value)
.Fill((v, i) =>
{
switch (i % 12)
{
case 0: return Brushes.ForestGreen; //january
case 1: return Brushes.Coral; //february
case 2: return Brushes.Crimson; //march
case 3: return Brushes.OrangeRed; //april
case 4: return Brushes.DarkViolet; //may
case 5: return Brushes.Chocolate; //june
case 6: return Brushes.MediumVioletRed; //july
case 7: return Brushes.SteelBlue; //august
case 8: return Brushes.Orange; //september
case 9: return Brushes.Teal; //october
case 10: return Brushes.RosyBrown; //november
case 11: return Brushes.YellowGreen; //december
default: return Brushes.Red;
}
});
Charting.For<double>(doubleMapperWithMonthColors, SeriesOrientation.Horizontal);
}
来源:https://stackoverflow.com/questions/56181200/individually-colored-data-points-in-livecharts-wpf