7、LiveCharts--常用属性介绍(三)

前言:上一篇介绍了LiveCharts2中图表的基本类型及示例复现,基本都是数据的展示,仅仅是数据,图表其他的一些附属属性并没有,而且横坐标都是按依次增加的,纵坐标是我们设置的数据,这一篇就讲下图表的一些其他附属属性。 

笔者这里以折线图作为示例。

常用属性

折线图主要组件就是这四个,数据、坐标、提示工具、图例。

But notice in the previous code snippet we did not specify the Axes, Tooltip, Legend or the series colors, this is because LiveCharts will decide them based on the current theme of the library, you can also customize any of these properties when you require it, this article will cover the most common scenarios. 

之前我们并没有设置坐标系、提示框、图例等,因为框架帮我们设置了。

一、Series

There are multiple series available in the library, you can add one or mix them all in the same chart, every series has unique properties, any image bellow is a link to an article explaining more about them.

动态库中有多个可用数据,可以在图表中添加一个或多个,每个数据都有独特的属性。

以Line Series为例介绍下它的属性

1.1 Name 、Values property

name属性没什么好说的,values属性倒是内容比较多。

The Values property is of type IEnumerable<T>, this means that you can use any object that implements the IEnumerable<T> interface, such as ArrayList<T> or ObservableCollection<T>, this property contains the data to plot, you can use any type as the generic argument (<T>) as soon as you let the library how to handle it, the library already knows how to handle multiple types, but you can register any type and teach the library how to handle any object in a chart, for more information please see the mappers article.

Values属性是IEnumerable<T>类型,用户可以灵活使用这个属性,这个属性就是给图表数据去绘制的,至于IEnumerable<T>类型中的T(泛型)可以是任意类型,但是需要注册,具体的参考mappers相关文章。

SeriesCollection = new ISeries[]
{
    new LineSeriesProps<int>
    {
        Values = new []{ 2, 5, 4, 2, 6 },
        Name = "Income", 
        Stroke = null
    },
    new LineSeriesProps<int>
    {
        Values = new []{ 3, 7, 2, 9, 4 },
        Name = "Outcome", 
        Stroke = null
    }
};
// == 自定义类型和mapper == 
public class City 
{
    public string Name { get; set; }
    public double Population { get; set; }
}
//我们必须让series知道怎么去处理我们自定义的city类 
// 使用Mapping属性从我们自定义的city类中的一个point
// 同样也可以将map注册成全局的
// 更多mappers信息查看:
// https://lvcharts.com/docs/wpf/2.0.0-beta.300/Overview.Mappers
var citiesSeries = new LineSeriesProps<City>
{
    Values = new City[]
    { 
        new City { Name = "Tokio", Population = 9 },
        new City { Name = "New York", Population = 11 },
        new City { Name = "Mexico City", Population = 10 },
    },
    Mapping = (city, point) =>
    {
        // 我们数据集合中的city会被调用
         
        // 用户必须将坐标映射到点上
        // 将自定义类中的Population属性作为第一个参数(通常是Y)
        point.PrimaryValue = (float)city.Population;

        // 使用自定义类city的索引作为第二个参数
        // (通常是 X)
        point.SecondaryValue = point.Context.Index;
    }
};

1.2 Data labels

Data labels are labels for every point in a series, there are multiple properties to customize them

数据标签,下面看图就明白了

new LineSeriesProps<double>
{
    DataLabelsSize = 20,
    DataLabelsPaint = new SolidColorPaint(SKColors.Blue),
    // all the available positions at:
    // https://lvcharts.com/api/2.0.0-beta.300/LiveChartsCore.Measure.DataLabelsPosition
    DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.Top,
    // The DataLabelsFormatter is a function 
    // that takes the current point as parameter
    // and returns a string.
    // in this case we returned the PrimaryValue property as currency
    DataLabelsFormatter = (point) => point.PrimaryValue.ToString("C2"),
    Values = new ObservableCollection<double> { 2, 1, 3, 5, 3, 4, 6 },
    Fill = null
}

1.3 Stroke property

就是通过数据画出来的线的粗细、颜色等属性。 

Series = new ISeries[]
{
    new LineSeries<int>
    {
        Values = new [] { 4, 4, 7, 2, 8 },
        Stroke = new SolidColorPaint(SKColors.Blue) { StrokeThickness = 4 }, 
        Fill = null,
        GeometryFill = null,
        GeometryStroke = null
    },
    new LineSeries<int>
    {
        Values = new [] { 7, 5, 3, 2, 6 },
        Stroke = new SolidColorPaint(SKColors.Red) { StrokeThickness = 8 }, 
        Fill = null,
        GeometryFill = null,
        GeometryStroke = null
    },
    new LineSeries<int>
    {
        Values = new [] { 4, 2, 5, 3, 9 },
        Stroke = new SolidColorPaint(SKColors.Green) { StrokeThickness = 1 }, 
        Fill = null,
        GeometryFill = null,
        GeometryStroke = null
    }
};

1.4 Fill property

填充数据线下面的内容。 

Series = new ISeries[]
{
    new LineSeries<int>
    {
        Values = new [] { 4, 4, 7, 2, 8 },
        Fill = new SolidColorPaint(SKColors.Blue.WithAlpha(90)), 
        Stroke = null,
        GeometryFill = null,
        GeometryStroke = null
    },
    new LineSeries<int>
    {
        Values = new [] { 7, 5, 3, 2, 6 },
        Fill = new SolidColorPaint(SKColors.Red.WithAlpha(90)), 
        Stroke = null,
        GeometryFill = null,
        GeometryStroke = null
    },
    new LineSeries<int>
    {
        Values = new [] { 4, 2, 5, 3, 9 },
        Fill = new SolidColorPaint(SKColors.Green.WithAlpha(90)), 
        Stroke = null,
        GeometryFill = null,
        GeometryStroke = null
    }
};

1.5 GeometryFill and GeometryStroke properties

 The geometry is the circle shape (by default) that the line series draws for every point, you can customize the fill and stroke of this shape, if none of these properties are set then LiveCharts will create them based on the series position in your series collection and the current theme.

默认是圆形的,可以自定义形状,就是下面这东西。

Series = new ISeries[]
{
    new LineSeries<int>
    {
        Values = new [] { 4, 4, 7, 2, 8 },
        Stroke = new SolidColorPaint(SKColors.Blue) { StrokeThickness = 4 },
        Fill = null,
        GeometryFill = new SolidColorPaint(SKColors.AliceBlue), 
        GeometryStroke = new SolidColorPaint(SKColors.Gray) { StrokeThickness = 4 } 
    },
    new LineSeries<int>
    {
        Values = new [] { 7, 5, 3, 2, 6 },
        Stroke = new SolidColorPaint(SKColors.Red) { StrokeThickness = 8 },
        Fill = null,
        GeometryFill = new SolidColorPaint(SKColors.IndianRed), 
        GeometryStroke = new SolidColorPaint(SKColors.DarkSalmon) { StrokeThickness = 8 } 
    }
};

1.6 GeometrySize property

就是上面每个点的形状大小

Series = new ISeries[]
{
    new LineSeries<int>
    {
        Values = new [] { 4, 4, 7, 2, 8 },
        GeometrySize = 10 
    },
    new LineSeries<int>
    {
        Values = new [] { 7, 5, 3, 2, 6 },
        GeometrySize = 30 
    }
};

1.7 LineSmoothness property

Determines if the series line is straight or curved, this property is of type double and goes from 0 to 1 any other value will be ignored, where 0 is straight and 1 is the most curved line.

决定线是直的还是弯曲的,这个属性值是double类型,值大小从0-1,0是直的,1代表弯的。

Series = new ISeries[]
{
    new LineSeries<int>
    {
        Values = new [] { 5, 4, 7, 3, 8 },
        LineSmoothness = 0 
    },
    new LineSeries<int>
    {
        Values = new [] { 7, 2, 6, 2, 6 },
        LineSmoothness = 1 
    }
};

1.8 EnableNullSplitting property

This property is enabled by default (true), it has a performance cost and allows the series to create gaps, when the series finds a null instance then the series will create a gap.

线中间出现缺口

Series = new ISeries[]
{
    new LineSeries<int?>
    {
        Values = new int?[] 
        { 
            5, 
            4, 
            2, 
            null, 
            3, 
            8, 
            6 
        },
        LineSmoothness = 0
    }
};

1.9 Plotting custom types

You can teach LiveCharts to plot anything, imagine the case where we have an array of the City class defined bellow:

我们可以教给LiveChart去画任何事情,想象以下我们自定义了一个city类。

public class City
{
    public string Name { get; set; }
    public double Population { get; set; }
    public double LandArea { get; set; }
}

You can register this type globally, this means that every time LiveCharts finds a City instance in a chart it will use the mapper we registered, global mappers are unique for a type, if you need to plot multiple properties then you should use local mappers.

将其注册成全局的,这样,每次LiveCharts看到City这个数据类型,就会用mapper来注册,如果像哟啊使用多种属性,就需要使用本地mapper了

LiveCharts.Configure(config =>
    config
        .HasMap<City>((city, point) =>
        {
            // in this lambda function we take an instance of the City class (see city parameter)
            // and the point in the chart for that instance (see point parameter)
            // LiveCharts will call this method for every instance of our City class array,
            // now we need to populate the point coordinates from our City instance to our point

            // in this case we will use the Population property as our primary value (normally the Y coordinate)
            point.PrimaryValue = (float)city.Population;

            // then the secondary value (normally the X coordinate)
            // will be the index of city in our cities array
            point.SecondaryValue = point.Context.Index;

            // but you can use another property of the city class as the X coordinate
            // for example lets use the LandArea property to create a plot that compares
            // Population and LandArea in chart:

            // point.SecondaryValue = (float)city.LandArea;
        })
        .HasMap<Foo>(...) // you can register more types here using our fluent syntax
        .HasMap<Bar>(...)
    );

Now we are ready to plot cities all over our application:

下面开始用

Series = new[]
{
    new LineSeries<City>
    {
        Name = "Population",
        TooltipLabelFormatter = point => $"{point.Model.Name} {point.PrimaryValue:N2}M",
        Values = new[]
        {
            new City { Name = "Tokyo", Population = 4, LandArea = 3 },
            new City { Name = "New York", Population = 6, LandArea = 4 },
            new City { Name = "Seoul", Population = 2, LandArea = 1 },
            new City { Name = "Moscow", Population = 8, LandArea = 7 },
            new City { Name = "Shanghai", Population = 3, LandArea = 2 },
            new City { Name = "Guadalajara", Population = 4, LandArea = 5 }
        }
    }
};

Alternatively you could create a local mapper that will only work for a specific series, global mappers will be ignored when the series Mapping property is not null.

或者可以创建一个本地mapper

var cities = new[]
{
    new City { Name = "Tokyo", Population = 4, LandArea = 3 },
    new City { Name = "New York", Population = 6, LandArea = 4 },
    new City { Name = "Seoul", Population = 2, LandArea = 1 },
    new City { Name = "Moscow", Population = 8, LandArea = 7 },
    new City { Name = "Shanghai", Population = 3, LandArea = 2 },
    new City { Name = "Guadalajara", Population = 4, LandArea = 5 }
};

Series = new[]
{
    // this series draws the Population property in the Y axis
    new LineSeries<City>
    {
        Name = "Population",
        TooltipLabelFormatter = point => $"{point.Model.Name} population: {point.PrimaryValue:N2}M",
        Values = cities,
        Mapping = (city, point) =>
        {
            point.PrimaryValue = (float)city.Population;
            point.SecondaryValue = point.Context.Index;
        }
    },

    // draws the LandArea property in the Y axis
    new LineSeries<City>
    {
        Name = "Population",
        TooltipLabelFormatter = (point) => $"{point.Model.Name} area: {point.PrimaryValue:N2}KM2",
        Values = cities,
        Mapping = (city, point) =>
        {
            point.PrimaryValue = (float)city.LandArea;
            point.SecondaryValue = point.Context.Index;
        }
    },

    // compares Population (Y) and LandArea (Y)
    //new LineSeries<City>
    //{
    //    Name = "Population",
    //    TooltipLabelFormatter = (point) => $"{point.Model.Name} population: {point.PrimaryValue:N2}M, area: {point.SecondaryValue}KM2",
    //    Values = cities,
    //    Mapping = (city, point) =>
    //    {
    //        point.PrimaryValue = (float)city.Population;
    //        point.SecondaryValue = (float)city.LandArea;
    //    }
    //}
};

1.10 Custom geometries

You can use any geometry to represent a point in a line series.

可以使用任和几何形状代替线上面每个点

Series = new List<ISeries>
{
    // use the second argument type to specify the geometry to draw for every point
    // there are already many predefined geometries in the
    // LiveChartsCore.SkiaSharpView.Drawing.Geometries namespace
    new LineSeries<double, LiveChartsCore.SkiaSharpView.Drawing.Geometries.RectangleGeometry>
    {
        Values = new List<double> { 3, 3, -3, -2, -4, -3, -1 },
        Fill = null,
        LineSmoothness = 1
    },

    // you can also define your own SVG geometry
    new LineSeries<double, MyGeometry>
    {
        Values = new List<double> { -2, 2, 1, 3, -1, 4, 3 },
        Stroke = new SolidColorPaint(SKColors.DarkOliveGreen, 3),
        Fill = null,
        GeometryStroke = null,
        GeometryFill = new SolidColorPaint(SKColors.DarkOliveGreen),
        GeometrySize = 40
    }
};

1.11 DataPadding

The data padding is the minimum distance from the edges of the series to the axis limits, it is of type System.Drawing.PointF both coordinates (X and Y) goes from 0 to 1, where 0 is nothing and 1 is the axis tick an axis tick is the separation between every label or separator (even if they are not visible).

If this property is not set, the library will set it according to the series type, take a look at the following samples:

数据距离坐标轴的距离

new LineSeries<double>
{
    DataPadding = new System.Drawing.PointF(0, 0),
    Values = new ObservableCollection { 2, 1, 3, 5, 3, 4, 6 },
    GeometryStroke = null,
    GeometryFill = null,
    Fill = null
}

 But you can remove the padding only from an axis, for example:

也可以将padding从axis去除

new LineSeries<double>
{
    DataPadding = new System.Drawing.PointF(0.5f, 0),
    Values = new ObservableCollection<double> { 2, 1, 3, 5, 3, 4, 6 },
    GeometryStroke = null,
    GeometryFill = null,
    Fill = null
}

 Or you can increase the distance:

或者,增加距离

new LineSeries<double>
{
    DataPadding = new System.Drawing.PointF(2, 2),
    Values = new ObservableCollection<double> { 2, 1, 3, 5, 3, 4, 6 },
    GeometryStroke = null,
    GeometryFill = null,
    Fill = null
}

二、Axes

The following diagram illustrates an axis and its main components:

下图说明了axis和它的主要组件

xy坐标轴标签,xy轴值之间的间隙大小。

The cartesian chart control has the XAxes and YAxes properties, both of type IEnumerable<IAxis> by default when you do not set these properties, they will be an array containing only one element of the Axis class (new Axis[] { new Axis() }).

笛卡尔表有XAxes 和 YAxes属性,这俩默认都是IEnumerable<IAxis> 类型,它是一个仅仅包含一个Axis类元素的数组

2.1 Zooming and Panning

Both of these features are directly related to the MaxLimit and MinLimit properties, zooming occurs when the mouse wheel moves or when the pinch gesture occurs, the panning is called when the pointer goes down, moves and then goes up

Zooming is disabled by default, you must set the ZoomMode property to XY or Both, normally the X mode is the most accurate for horizontal series (LineSeries, ColumnSeries), the Y mode for vertical series (RowSeries) and the Both mode for Heat or Scatter series.

可以通过鼠标滚轮缩放xy轴,默认是不能缩放的,需要设置下ZoomMode属性的值,比如X、Y或者Both。

X Mode:

When the user interacts with the chart, He/She/* is only moving the chart in the X axis direction, the Y axis range is calculated automatically by the library to fit all the visible points in the X axis.

如果设置ZoomMode属性的值位X模式,用户只能缩放X轴,Y轴范围根据库中自定义的自动缩放。

<lvc:CartesianChart
    Series="{Binding Series}"
    TooltipPosition="Hidden"
    ZoomMode="X"> 
</lvc:CartesianChart>

Y Mode:

When the user interacts with the chart, He/She/* is only moving the chart in the Y axis direction, the X axis range is calculated automatically by the library to fit all the visible points in the Y axis.

同理,设置列Y模式,就只能滚动Y轴,x轴自动缩放。

<lvc:CartesianChart
    Series="{Binding Series}"
    TooltipPosition="Hidden"
    ZoomMode="Y"> 
</lvc:CartesianChart>

 

Both Mode:

Both axis are moved by the user, this method could lead to the user to get lost in the canvas, you probably need to implement a button to reset the zoom to the data in the chart (settings MinLimit and MaxLimit properties to null).

xy轴同时缩放。但是最好设置个button用来reset这个缩放。

<lvc:CartesianChart
    Series="{Binding Series}"
    TooltipPosition="Hidden"
    ZoomMode="Both"> 
</lvc:CartesianChart>

2.2 MaxLimit and MinLimit properties

These properties control the zooming and panning of a chart, both properties are of type of double?, you can indicate the visible range of an axis setting these properties. For example, imagine you are plotting a LineSeries that goes from 0 to 100 in the X axis, but you only need to show to the user the first 10 points (paging), in this case you could set the MinLimit property to 0 and the MaxLimit to 10.

设置缩放最大最小步长。

2.3 Clearing the current zooming or panning

Setting MinLimit and MaxLimit properties to null will clear the current zooming or panning, and will let the chart fit the view of the chart to the available data in the chart, the default value of both properties is null.

MinLimit 和MaxLimit属性设置为null就取消缩放了。

2.4 MinStep property

The Step defines the interval or distance between every separator and label in the axis, LiveCharts will calculate it automatically based on the chart data and the chart size size, but you can configure the minimum value this property could be, for example in the case where you don't want decimal separations in the axis labels, you could set the MinStep property to 1, this way, when the calculated step is less that 1 the library will force it to be 1.

设置坐标系值间隔最小值

2.5 Position property

The axis position property is type AxisPosition, it is an enum containing only 2 options, Start and End the Start position places the axis at the bottom for X axes and at the left for Y axes and the End position places the axis at the top for X axes and at the right for Y axes.

axis位置属性类型是AxisPosition,是一个包含两个值的枚举属性--Start 和End,Start属性会将x轴的值设置在下面,把y轴的值设置在左边,end就是另两边了。

2.6 LabelsPaint and SeparatorsPaint properties 

You can set the color, use dashed lines, build gradients for the axis name, labels and separators.

设置axis 名字, 标签 and 分割线的颜色

using LiveChartsCore;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using LiveChartsCore.SkiaSharpView.Painting.Effects;
using SkiaSharp;

namespace ViewModelsSamples.Bars.Basic
{
    public class ViewModel
    {
        public ISeries[] Series { get; set; }
            = new ISeries[] { new ColumnSeries<int> { Values = new[] { 2, 5, 4, -2, 4, -3, 5 } } };

        public Axis[] XAxes { get; set; }
            = new Axis[]
            {
                new Axis
                {
                    Name = "X Axis",
                    NamePaint = new SolidColorPaint(SKColors.Black), 

                    LabelsPaint = new SolidColorPaint(SKColors.Blue), 
                    TextSize = 10,

                    SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray) { StrokeThickness = 2 }  
                }
            };

        public Axis[] YAxes { get; set; }
            = new Axis[]
            {
                new Axis
                {
                    Name = "Y Axis",
                    NamePaint = new SolidColorPaint(SKColors.Red), 

                    LabelsPaint = new SolidColorPaint(SKColors.Green), 
                    TextSize = 20,

                    SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray) 
                    { 
                        StrokeThickness = 2, 
                        PathEffect = new DashEffect(new float[] { 3, 3 }) 
                    } 
                }
            };
    }
}
<lvc:CartesianChart
    Series="{Binding Series}"
    XAxes="{Binding XAxes}"
    YAxes="{Binding YAxes}">
</lvc:CartesianChart>

2.7 Labels vs Labeler properties

There are 2 ways to format and axis labels, using the Labels property and using the Labeler property, you must normally use the Labels property to indicate names, and the Labeler property to give format to the current label.

The labels property is a collection of string, if this property is not null, then the axis label will be pulled from the labels collection, the label is mapped to the chart based on the position of the label and the position of the point, both integers, if the axis requires a label outside the bounds of the labels collection, then the index will be returned as the label, default value is null.

可以通过Labels和Labeler属性格式化axis标签。我们平常用的最多的是Labels去显示names属性,并通过Labeler属性去格式化lable。

Series = new ObservableCollection<ISeries>
{
    new ColumnSeries<int>
    {
        Values = new ObservableCollection<int> { 200, 558, 458, 249 },
    }
};

XAxes = new List<Axis>
{
    new Axis
    {
        // Use the labels property to define named labels.
        Labels = new string[] { "Anne", "Johnny", "Zac", "Rosa" } 
    }
};

YAxes = new List<Axis>
{
    new Axis
    {
        // Now the Y axis we will display labels as currency
        // LiveCharts provides some common formatters
        // in this case we are using the currency formatter.
        Labeler = Labelers.Currency 

        // you could also build your own currency formatter
        // for example:
        // Labeler = (value) => value.ToString("C")

        // But the one that LiveCharts provides creates shorter labels when
        // the amount is in millions or trillions
    }
};

2.8 LabelsRotation property

Indicates the axis labels rotation in degrees, in the following image we have a rotation of 45 degrees in the Y axis.

标签旋转角度 

YAxes = new List<Axis>
{
    new Axis    
    {
        LabelsRotation = 45
    }
};

2.9 Multiple axes

Both of these properties are collections because the library supports to have more than one axis, the following sample illustrates how to create a chart that uses multiple axes:

多坐标轴显示

三、Tooltips

Tooltips are popups that help the user to read a chart as the pointer moves.

提示框是个弹出窗口,帮助我们在移动鼠标时读取鼠标指定的图表的数据。

3.1 TooltipPosition property

You can place a tooltip at TopBottomLeftRightCenter or Hidden positions, for now tooltips for the PieChart class only support the Center position, default value is Top.

Notice the Hidden position will disable tooltips in a chart.

tooltip放置位置可以是上、下、左、右、中、隐藏,饼状图只支持中间,其他的默认时放在上面,注意:如果设置成隐藏将会使tooltip不能使用在图表中。

3.2 TooltipFindingStrategy property

Every point drawn by the library defines a HoverArea, it defines an area in the chart that "triggers" the point, it is specially important to fire tooltips, a point will be included in a tooltip when the hover area was triggered by the pointer position.

The TooltipFindingStrategy property determines the hover area planes (X or Y) that a chart will use to trigger the HoverArea instances. In a chart, the following options are available:

动态库中定义了个悬停区域,用于触发图表中的点,TooltipFindingStrategy 属性决定悬停区域显示X轴值还是Y轴值,这个计划会用于触发悬停区域实例。下面使可选属性值:

CompareAll: Selects all the points whose hover area contain the pointer position.

CompareAll可以同时显示X和Y轴数据。

CompareOnlyX: Selects all the points whose hover area contain the pointer position, but it ignores the Y plane.

只显示X轴数据。

CompareOnlyY: Selects all the points whose hover area contain the pointer position, but it ignores the X plane.

只显示Y轴数据。

<lvc:CartesianChart
    Series="{Binding Series}"
    TooltipFindingStrategy="CompareOnlyX">
</lvc:CartesianChart>
<!--只显示X值-->

XY轴值都显示

 

只显示X轴值

 

只显示Y轴值

3.3 Tooltip point text

给显示的XY轴值加上代表的数值含义

You can define the text the tooltip will display for a given point, using the Series.TooltipLabelFormatter property, this property is of type Func<ChartPoint, string> this means that is is a function, that takes a point as parameter and returns a string, the point will be injected by LiveCharts in this function to get a string out of it when it requires to build the text for a point in a tooltip, the injected point will be different as the user moves the pointer over the user interface.

By default the library already defines a default TooltipLabelFormatter for every series, all the series have a different formatter, but generally the default value uses the Series.Name and the ChartPoint.PrimaryValue properties, the following code snippet illustrates how to build a custom tooltip formatter.

通过Series.TooltipLabelFormatter属性给要显示的点加上文字描述。这个属性是个Func<ChartPoint, string>类型,这是个方法,放进去point,返回一个string。

默认情况下,框架帮每一个series定义了这个属性。全部的series都有一个不同的formatter,但是总体上默认的值是使用Series的Name属性和ChartPoint的PrimaryValue属性,下面用示例演示下怎么自定义tooltip formatter。

new LineSeries<double>
{
    Name = "Sales",
    Values = new ObservableCollection<double> { 200, 558, 458 },
    // 按照下面的格式进行格式化的话
    // 当鼠标移动到点200的时候,tooltip会显示
    // Sales: 200
    TooltipLabelFormatter =
        (chartPoint) => $"{chartPoint.Context.Series.Name}: {chartPoint.PrimaryValue}"
},

new ColumnSeries<double>
{
    Name = "Sales 2",
    Values = new ObservableCollection<double> { 250, 350, 240 },
    // 使用货币格式化来显示初始值
    // 结果: Sales 2: $200.00
    TooltipLabelFormatter =
        (chartPoint) => $"{chartPoint.Context.Series.Name}: {chartPoint.PrimaryValue:C2}"
},

new StepLineSeries<ObservablePoint>
{
    Name = "Average",
    Values = new ObservableCollection<ObservablePoint>
    {
        new ObservablePoint(10, 5),
        new ObservablePoint(5, 8)
    },
    // 同时显示xy轴
    // 结果: Average: 10, 5
    TooltipLabelFormatter =
        (chartPoint) => $"{chartPoint.Context.Series.Name}: {chartPoint.SecondaryValue}, {chartPoint.PrimaryValue}"
},

new ColumnSeries<ObservablePoint>
{
    Values = new ObservableCollection<double> { 250, 350, 240 },
    // 任和东西都可以代替键部分
    // result: Sales at this moment: $200.00
    TooltipLabelFormatter =
        (chartPoint) => $"Sales at this moment: {chartPoint.PrimaryValue:C2}"
}

3.4 Styling tooltips

提示框的样式,最简单的就是字体、颜色、位置等。

<lvc:CartesianChart
    Series="{Binding Series}"
    TooltipPosition="Left"
    TooltipFontFamily="Courier New"
    TooltipFontSize="25"
    TooltipTextBrush="#f2f4c3"
    TooltipBackground="#480032">
</lvc:CartesianChart>

3.5 Custom template

自定义模板

<UserControl x:Class="WPFSample.General.TemplatedTooltips.View"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
             xmlns:vms="clr-namespace:ViewModelsSamples.General.TemplatedTooltips;assembly=ViewModelsSamples"
             xmlns:ctx="clr-namespace:LiveChartsCore.Kernel;assembly=LiveChartsCore">
    <UserControl.DataContext>
        <vms:ViewModel/>
    </UserControl.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <lvc:CartesianChart Grid.Row="0" Series="{Binding Series}" TooltipPosition="Top" >
            <lvc:CartesianChart.TooltipTemplate>
                <DataTemplate>
                    <Border Background="#303030">
                        <ItemsControl ItemsSource="{Binding Points, RelativeSource={RelativeSource AncestorType=lvc:DefaultTooltip}}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Vertical" />
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate DataType="{x:Type ctx:ChartPoint}">
                                    <Border Padding="7 5">
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="{Binding AsTooltipString}" Margin="0 0 8 0" Foreground="AntiqueWhite" />
                                            <lvc:MotionCanvas Margin="0 0 8 0" 
                                                PaintTasks="{Binding Context.Series.CanvasSchedule.PaintSchedules}"
                                                Width="{Binding Context.Series.CanvasSchedule.Width}"
                                                Height="{Binding Context.Series.CanvasSchedule.Height}"
                                                VerticalAlignment="Center"/>
                                        </StackPanel>
                                    </Border>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </Border>
                </DataTemplate>
            </lvc:CartesianChart.TooltipTemplate>
        </lvc:CartesianChart>
    </Grid>
</UserControl>

 

四、Legends

A legend is a visual element that displays a list with the name, stroke and fills of the series in a chart:

图例是一个用来显示图表中数据的名字、画笔等属性的可视化元素

You can place a legend at TopBottomLeftRight or Hidden positions, notice the Hidden position will disable legends in a chart, default value is Hidden.

图例可以放在上、下、左、右位置或者隐藏,注意默认是隐藏的

<lvc:CartesianChart
    Series="{Binding Series}"
    LegendPosition="Top">
</lvc:CartesianChart>
<lvc:CartesianChart
    Series="{Binding Series}"
    LegendPosition="Bottom">
</lvc:CartesianChart>
<lvc:CartesianChart
    Series="{Binding Series}"
    LegendPosition="Left">
</lvc:CartesianChart>
<lvc:CartesianChart
    Series="{Binding Series}"
    LegendPosition="Right">
</lvc:CartesianChart>
<lvc:CartesianChart
    Series="{Binding Series}"
    LegendPosition="Hidden">
</lvc:CartesianChart>

4.1 styling legends

A chart exposes many properties to quickly style a legend:

可以通过chart暴露的多个属性快速构建一个快速的style

<lvc:CartesianChart
    Series="{Binding Series}"
    LegendPosition="Left"
    LegendFontFamily="Courier New"
    LegendFontSize="25"
    LegendTextBrush="#f2f4c3"
    LegendBackground="#480032">
</lvc:CartesianChart>

4.2 Custom template

<lvc:CartesianChart Grid.Row="0" Series="{Binding Series}" LegendPosition="Right" >
            <lvc:CartesianChart.LegendTemplate>
                <DataTemplate>
                    <ItemsControl ItemsSource="{Binding Series, RelativeSource={RelativeSource AncestorType=lvc:DefaultLegend}}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <WrapPanel HorizontalAlignment="Center" VerticalAlignment="Center" 
                                    Orientation="{Binding Orientation, RelativeSource={RelativeSource AncestorType=lvc:DefaultLegend}}" />
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Border Padding="15 4" Background="#F5F5DC">
                                    <StackPanel Orientation="Horizontal">
                                        <TextBlock
                                            Text="{Binding Name}"
                                            VerticalAlignment="Center"/>
                                        <lvc:MotionCanvas
                                            Margin="8 0 0 0"
                                            PaintTasks="{Binding CanvasSchedule.PaintSchedules}"
                                            Width="{Binding CanvasSchedule.Width}"
                                            Height="{Binding CanvasSchedule.Height}"
                                            VerticalAlignment="Center"/>
                                    </StackPanel>
                                </Border>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </DataTemplate>
            </lvc:CartesianChart.LegendTemplate>
        </lvc:CartesianChart>
基于.NET Framework的WinForm项目可以使用图表插件来实现数据可视化,其中一个常用的图表插件是LiveCharts。下面是使用LiveCharts在WinForm项目中创建图表的示例代码: 首先,确保你的WinForm项目已经引用了LiveCharts库。你可以通过NuGet包管理器来添加引用,或者手动下载并添加引用。 接下来,在你的WinForm窗体中添加一个Chart控件,可以通过拖拽方式添加或者在代码中动态创建。 然后,在窗体的代码文件中,导入LiveCharts命名空间,并使用以下代码来创建和配置图表: ```csharp using LiveCharts; using LiveCharts.Wpf; // 创建一个SeriesCollection对象,用于存储图表的数据系列 SeriesCollection seriesCollection = new SeriesCollection(); // 创建一个LineSeries对象,表示折线图 LineSeries lineSeries = new LineSeries(); // 设置折线图的标题和数据 lineSeries.Title = "折线图"; lineSeries.Values = new ChartValues<double> { 1, 3, 2, 8, 5 }; // 将折线图添加到SeriesCollection中 seriesCollection.Add(lineSeries); // 将SeriesCollection对象设置为Chart控件的Series属性 chart.Series = seriesCollection; ``` 以上代码创建了一个折线图,并将其添加到Chart控件中显示。你可以根据需要修改图表的类型、样式和数据。 请注意,以上示例代码是基于C#语言的WinForm项目,使用LiveCharts库来创建图表。如果你使用的是其他语言或其他图表插件,可能会有一些差异。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值