一、前段时间用了一下d3,对它的实现比较感兴趣,就把源码下载下来研究了下,ChartPlotter类主要类,画图的地方有:
1.DataSource数据构成的图形
2.横纵坐标的标尺和数字
3.数据背后的网格
4.还有一些header,footer和legend就先略过
二、各个部分都继承自了FrameworkElement,间接继承UIElement,不论是鼠标键盘,还是数据源改变来改变图形的显示,主要是通过触发事件的时候调取UIElement的方法:
InvalidateVisual() MSDN解释:使元素的呈现无效,并强制执行完整的新布局处理过程,布局循环完成后,调用UIElement.OnRender(...)
再重写OnRender方法,通过坐标系变化,再把改变后的图形呈现画出来
对于横纵坐标系和网格,用GeometryGroup LineGeomety,每一次窗体大小改变,或者鼠标键盘移动的时候,就按照移动完的位置重新绘制
而对于展示数据的图形,用的是StreamGeometry,MSDN的解释:
定义几何形状,并使用StreamGeometryContext进行描述,此几何图形是PathGeometry的轻量级替代图形:它不支持数据绑定、动画和移动
//开始用Path来画,Path不能动态添加,然后用Line画多了就卡,还是只有这个轻量级的最适合画动态图
三、部分代码
private void Update()
{
InvalidateVisual();
}
protected override void OnRender(DrawingContext context)
{
FilterPoints();
StreamGeometry geometry = new StreamGeometry();
using(StreamGeometryContext geoContext = geometry.Open())
{
geoContext.BeginFigure(StartPoint, false, false);
geoContext.PolyLineTo(filterPoints, true, true);
}
geometry.Freeze();
context.DrawGeometry(null, new Pen(Brushes.Red, 2), geometry);
}
五、子控件添加
ChartPlotter在xaml里面可以添加横纵坐标,header,footer等子控件,这是在Plotter类增加了一个修饰属性[ContentProperty("Children")]
ChartPlotter : Plotter2D : Plotter
Children是Plotter的一个属性,ChildrenCollection : D3Collection<T> : ObservableCollection<T>集合类型,装的就是chartplotter里面这些图形,网格,坐标系和图例等都继承自IPlotterElement的控件类,所以在xaml下加一个IPlotterElement类的控件,Children集合就加一个元素,触发Children的CollectionChanged,再把控件显示出来
六、命名空间
DynamicDataDisplay在xaml里可以直接导入命名空间xmlns:d3="http://research.microsoft.com/DynamicDataDisplay/1.0"而不需要分别导入各个命名空间
[assembly: XmlnsDefinition("http://r.../1.0", "Micro....Display"]
[assembly: XmlnsDefinition("http://r.../1.0", "Micro....Navigation")]
...
把项目所有的命名空间都加入了,所以只需要导入这个网站就行了