/// <summary> /// ExportToPng /// </summary> /// <param name="path"></param> /// <param name="surface"></param> public static void ExportToPng(Uri path, Visifire.Charts.Chart surface) { if (path == null) return; //Save current canvas transform 保存当前画布变换 Transform transform = surface.LayoutTransform; //reset current transform (in case it is scaled or rotated) 重设当前画布(如果缩放或旋转) surface.LayoutTransform = null; //Create a render bitmap and push the surface to it 创建一个渲染位图和表面 RenderTargetBitmap renderBitmap = new RenderTargetBitmap( (int)surface.Width, (int)surface.Height, 96d, 96d, PixelFormats.Pbgra32); renderBitmap.Render(surface); // Create a file stream for saving image using (FileStream outStream = new FileStream(path.LocalPath, FileMode.Create)) { //Use png encoder for our data PngBitmapEncoder encoder = new PngBitmapEncoder(); // push the rendered bitmap to it encoder.Frames.Add(BitmapFrame.Create(renderBitmap)); // save the data to the stream encoder.Save(outStream); } // Restore previously saved layout 恢复以前保存布局 surface.LayoutTransform = transform; }
private void AddDataSeries(string legendText, Visifire.Charts.DataSeries dataSeries, LineStyles style, SolidColorBrush brush, Visifire.Charts.RenderAs renderAs) { // 设置数据线的格式。 dataSeries.RenderAs = renderAs; dataSeries.LegendText = legendText; dataSeries.ShowInLegend = true; dataSeries.Color = brush; }
protected virtual void Save(String path, Visifire.Charts.ExportType exportType, Boolean showDilog) { if (_saveIconImage != null) { _saveIconImage.Visibility = Visibility.Collapsed; _toolTip.Hide(); _toolbarContainer.UpdateLayout(); } #if SL try { WriteableBitmap bitmap = new WriteableBitmap(this, null); #if !WP if (bitmap != null) { SaveFileDialog saveDlg = new SaveFileDialog(); saveDlg.Filter = "JPEG (*.jpg)|*.jpg|BMP (*.bmp)|*.bmp"; saveDlg.DefaultExt = ".jpg"; if ((bool)saveDlg.ShowDialog()) { using (Stream fs = saveDlg.OpenFile()) { String[] filename = saveDlg.SafeFileName.Split('.'); String fileExt; if (filename.Length >= 2) { fileExt = filename[filename.Length - 1]; exportType = (Visifire.Charts.ExportType)Enum.Parse(typeof(Visifire.Charts.ExportType), fileExt, true); } else exportType = Visifire.Charts.ExportType.Jpg; MemoryStream stream = Graphics.GetImageStream(bitmap, exportType); // Get Bytes from memory stream and write into IO stream byte[] binaryData = new Byte[stream.Length]; long bytesRead = stream.Read(binaryData, 0, (int)stream.Length); fs.Write(binaryData, 0, binaryData.Length); } } } #endif } catch (Exception ex) { if (_saveIconImage != null) { _saveIconImage.Visibility = Visibility.Visible; } System.Diagnostics.Debug.WriteLine("Note: Please make sure that Height and Width of the chart is set properly."); System.Diagnostics.Debug.WriteLine(ex.Message); } #else // Matrix m = PresentationSource.FromVisual(Application.Current.MainWindow).CompositionTarget.TransformToDevice; // double dx = m.M11* 96; // double dy = m.M22 * 96; // Save current canvas transform Transform transform = this.LayoutTransform; // reset current transform (in case it is scaled or rotated) _rootElement.LayoutTransform = null; // Create a render bitmap and push the surface to it RenderTargetBitmap renderBitmap = new RenderTargetBitmap( (int)(this.ActualWidth), (int)(this.ActualHeight), 96d, 96d, PixelFormats.Pbgra32); renderBitmap.Render(_rootElement); if (showDilog) { Microsoft.Win32.SaveFileDialog saveDlg = new Microsoft.Win32.SaveFileDialog(); saveDlg.Filter = "Jpg Files (*.jpg)|*.jpg|BMP Files (*.bmp)|*.bmp"; saveDlg.DefaultExt = ".jpg"; if ((bool)saveDlg.ShowDialog()) { BitmapEncoder encoder; if (saveDlg.FilterIndex == 2) encoder = new BmpBitmapEncoder(); else encoder = new JpegBitmapEncoder(); using (Stream fs = saveDlg.OpenFile()) { encoder.Frames.Add(BitmapFrame.Create(renderBitmap)); // save the data to the stream encoder.Save(fs); } } } else { path = System.IO.Path.GetFullPath(path.Trim()); String fileName = System.IO.Path.GetFileName(path); if (String.IsNullOrEmpty(fileName)) { fileName = "VisifireChart"; path += fileName; } switch (exportType) { case Visifire.Charts.ExportType.Bmp: path += ".bmp"; break; default: path += ".jpg"; break; } FileStream outStream; // Create a file stream for saving image using (outStream = new FileStream(path, FileMode.Create)) { BitmapEncoder encoder; switch (exportType) { case Visifire.Charts.ExportType.Bmp: encoder = new BmpBitmapEncoder(); break; default: encoder = new JpegBitmapEncoder(); break; } // push the rendered bitmap to it encoder.Frames.Add(BitmapFrame.Create(renderBitmap)); // save the data to the stream encoder.Save(outStream); } if (outStream == null) throw new System.IO.IOException("Unable to export the chart to an image as the specified path is invalid."); } // Restore previously saved layout _rootElement.LayoutTransform = transform; #endif if (_saveIconImage != null && ToolBarEnabled) _saveIconImage.Visibility = Visibility.Visible; }
internal static void UpdateVisualObject(RenderAs chartType, Visifire.Commons.ObservableObject sender, VcProperties property, object newValue, Boolean isAXisChanged) { Boolean isDataPoint = sender.GetType().Equals(typeof(DataPoint)); DataPoint dataPoint = sender as DataPoint; Chart chart = (sender as ObservableObject).Chart as Chart; switch (chartType) { case RenderAs.Column: case RenderAs.Bar: ColumnChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.Line: case RenderAs.Spline: LineChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.QuickLine: QuickLineChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.StepLine: StepLineChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.Point: PointChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.Bubble: BubbleChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.Area: AreaChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.StackedColumn: ColumnChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.StackedColumn100: ColumnChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.StackedBar: ColumnChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.StackedBar100: ColumnChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.Pie: //renderedCanvas = PieChart.GetVisualObjectForPieChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled); break; case RenderAs.Doughnut: //renderedCanvas = PieChart.GetVisualObjectForDoughnutChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled); break; case RenderAs.StackedArea: List<DataSeries> stackedAreaList = (from ds in chart.Series where ds.RenderAs == RenderAs.StackedArea select ds).ToList(); if (stackedAreaList.Count > 0) ColumnChart.Update(chart, stackedAreaList[0].RenderAs, stackedAreaList); chart.ChartArea.AttachEventsToolTipHref2DataSeries(); break; case RenderAs.StackedArea100: List<DataSeries> stackedArea100List = (from ds in chart.Series where ds.RenderAs == RenderAs.StackedArea select ds).ToList(); if (stackedArea100List.Count > 0) ColumnChart.Update(chart, stackedArea100List[0].RenderAs, stackedArea100List); chart.ChartArea.AttachEventsToolTipHref2DataSeries(); break; case RenderAs.SectionFunnel: case RenderAs.StreamLineFunnel: case RenderAs.Pyramid: //renderedCanvas = FunnelChart.GetVisualObjectForFunnelChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled, true); break; case RenderAs.Stock: StockChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.CandleStick: CandleStick.Update(sender, property, newValue, isAXisChanged); break; } //chart.ChartArea.AttachScrollEvents(); }
internal static void UpdateVisualObject(RenderAs chartType, Visifire.Commons.ObservableObject sender, VcProperties property, object newValue, Boolean isAXisChanged) { Boolean isDataPoint = sender.GetType().Equals(typeof(DataPoint)); DataPoint dataPoint = sender as DataPoint; Chart chart = (sender as ObservableObject).Chart as Chart; switch (chartType) { case RenderAs.Column: case RenderAs.Bar: ColumnChart.Update(sender, property, newValue, isAXisChanged); //ColumnChart.GetVisualObjectForColumnChart(width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; // renderedCanvas = BarChart.GetVisualObjectForBarChart(width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); case RenderAs.Line: //if (isAXisChanged && isDataPoint && chart._partialUpdateAnimation) //{ foreach (DataSeries ds in chart.Series) // { // //if (ds == dataPoint.Parent) // // continue; // foreach (DataPoint dp in ds.DataPoints) // { // RenderHelper.UpdateVisualObject(ds.RenderAs, dp, property, newValue, false); // } // } //} //else // LineChart.Update(sender, property, newValue); LineChart.Update(sender, property, newValue, isAXisChanged); break; case RenderAs.Point: PointChart.Update(sender, property, newValue, isAXisChanged); //renderedCanvas = PointChart.GetVisualObjectForPointChart(width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.Bubble: BubbleChart.Update(sender, property, newValue, isAXisChanged); //renderedCanvas = BubbleChart.GetVisualObjectForBubbleChart(width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.Area: AreaChart.Update(sender, property, newValue, isAXisChanged); //renderedCanvas = AreaChart.GetVisualObjectForAreaChart(width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.StackedColumn: ColumnChart.Update(sender, property, newValue, isAXisChanged); //renderedCanvas = ColumnChart.GetVisualObjectForStackedColumnChart(width, height, plotDetails, chart, plankDepth, animationEnabled); break; case RenderAs.StackedColumn100: ColumnChart.Update(sender, property, newValue, isAXisChanged); // renderedCanvas = ColumnChart.GetVisualObjectForStackedColumn100Chart(width, height, plotDetails, chart, plankDepth, animationEnabled); break; case RenderAs.StackedBar: ColumnChart.Update(sender, property, newValue, isAXisChanged); //renderedCanvas = BarChart.GetVisualObjectForStackedBarChart(width, height, plotDetails, chart, plankDepth, animationEnabled); break; case RenderAs.StackedBar100: ColumnChart.Update(sender, property, newValue, isAXisChanged); //renderedCanvas = BarChart.GetVisualObjectForStackedBar100Chart(width, height, plotDetails, chart, plankDepth, animationEnabled); break; case RenderAs.Pie: //renderedCanvas = PieChart.GetVisualObjectForPieChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled); break; case RenderAs.Doughnut: //renderedCanvas = PieChart.GetVisualObjectForDoughnutChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled); break; case RenderAs.StackedArea: //renderedCanvas = AreaChart.GetVisualObjectForStackedAreaChart(width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.StackedArea100: //renderedCanvas = AreaChart.GetVisualObjectForStackedArea100Chart(width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.SectionFunnel: //renderedCanvas = FunnelChart.GetVisualObjectForFunnelChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled, false); break; case RenderAs.StreamLineFunnel: //renderedCanvas = FunnelChart.GetVisualObjectForFunnelChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled, true); break; case RenderAs.Stock: StockChart.Update(sender, property, newValue, isAXisChanged); //renderedCanvas = StockChart.GetVisualObjectForStockChart(width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.CandleStick: CandleStick.Update(sender, property, newValue, isAXisChanged); //renderedCanvas = CandleStick.GetVisualObjectForCandleStick(width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; } chart.ChartArea.AttachScrollEvents(); }
/* public static ScrollViewer CreateScrollViewerFromXAML(Double scrollBarSize) { StringBuilder xaml = new StringBuilder(); xaml.Append("<ScrollViewer xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">"); xaml.Append("<ScrollViewer.Template>"); xaml.Append("<ControlTemplate TargetType=\"ScrollViewer\">"); xaml.Append("<Border BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" CornerRadius=\"2\">"); xaml.Append("<Grid Background=\"{TemplateBinding Background}\">"); xaml.Append("<Grid.ColumnDefinitions>"); xaml.Append("<ColumnDefinition Width=\"*\"/>"); xaml.Append("<ColumnDefinition Width=\"Auto\"/>"); xaml.Append("</Grid.ColumnDefinitions>"); xaml.Append("<Grid.RowDefinitions>"); xaml.Append("<RowDefinition Height=\"*\"/>"); xaml.Append("<RowDefinition Height=\"Auto\"/>"); xaml.Append("</Grid.RowDefinitions>"); xaml.Append("<ScrollContentPresenter x:Name=\"ScrollContentPresenter\" Cursor=\"{TemplateBinding Cursor}\" Margin=\"{TemplateBinding Padding}\" ContentTemplate=\"{TemplateBinding ContentTemplate}\"/>"); xaml.Append("<Rectangle Fill=\"#FFE9EEF4\" Grid.Column=\"1\" Grid.Row=\"1\"/>"); xaml.Append("<ScrollBar x:Name=\"VerticalScrollBar\" Margin=\"0,-1,-1,-1\" Width=\"18\" Visibility=\"{TemplateBinding ComputedVerticalScrollBarVisibility}\" IsTabStop=\"False\" Grid.Column=\"1\" Grid.Row=\"0\" Maximum=\"{TemplateBinding ScrollableHeight}\" Minimum=\"0\" Value=\"{TemplateBinding VerticalOffset}\" Orientation=\"Vertical\" ViewportSize=\"{TemplateBinding ViewportHeight}\"/>"); xaml.Append("<ScrollBar x:Name=\"HorizontalScrollBar\" Height=\"18\" Margin=\"-1,0,-1,-1\" Visibility=\"{TemplateBinding ComputedHorizontalScrollBarVisibility}\" IsTabStop=\"False\" Grid.Column=\"0\" Grid.Row=\"1\" Maximum=\"{TemplateBinding ScrollableWidth}\" Minimum=\"0\" Value=\"{TemplateBinding HorizontalOffset}\" Orientation=\"Horizontal\" ViewportSize=\"{TemplateBinding ViewportWidth}\"/>"); xaml.Append("</Grid>"); xaml.Append("</Border>"); xaml.Append("</ControlTemplate>"); xaml.Append("</ScrollViewer.Template>"); xaml.Append("</ScrollViewer>"); #if SL return (ScrollViewer) System.Windows.Markup.XamlReader.Load(xaml.ToString()); #else return (ScrollViewer)XamlReader.Load(new XmlTextReader(new System.IO.StringReader(xaml.ToString()))); #endif } */ #if SL /// <summary> /// Get image MemoryStream from WriteableBitmap /// </summary> /// <param name="bitmap">WriteableBitmap</param> /// <returns>MemoryStream</returns> public static System.IO.MemoryStream GetImageStream(WriteableBitmap bitmap, Visifire.Charts.ExportType exportTypes) { byte[][,] raster = ReadRasterInformation(bitmap); if (exportTypes == ExportType.Jpg) { return EncodeRasterInformationToStream(raster, ColorSpace.RGB); } else { int width = bitmap.PixelWidth; int height = bitmap.PixelHeight; System.IO.MemoryStream ms = new System.IO.MemoryStream(); // http://en.wikipedia.org/wiki/BMP_file_format #region BMP File Header(14 bytes) // Magic number(2 bytes):BM ms.WriteByte(0x42); ms.WriteByte(0x4D); // Size of the BMP file in bytes(4 bytes) long len = bitmap.Pixels.Length * 4 + 0x36; ms.WriteByte((byte)len); ms.WriteByte((byte)(len >> 8)); ms.WriteByte((byte)(len >> 16)); ms.WriteByte((byte)(len >> 24)); // Reserved(2 bytes) ms.WriteByte(0x00); ms.WriteByte(0x00); // Reserved(2 bytes) ms.WriteByte(0x00); ms.WriteByte(0x00); // Offset(4 bytes) ms.WriteByte(0x36); ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); #endregion // http://en.wikipedia.org/wiki/BMP_file_format #region Bitmap Information(40 bytes:Windows V3) // Size of this header(4 bytes) ms.WriteByte(0x28); ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); // Bitmap width in pixels(4 bytes) ms.WriteByte((byte)width); ms.WriteByte((byte)(width >> 8)); ms.WriteByte((byte)(width >> 16)); ms.WriteByte((byte)(width >> 24)); // Bitmap height in pixels(4 bytes) ms.WriteByte((byte)height); ms.WriteByte((byte)(height >> 8)); ms.WriteByte((byte)(height >> 16)); ms.WriteByte((byte)(height >> 24)); // Bumber of color planes(2 bytes) ms.WriteByte(0x01); ms.WriteByte(0x00); // Number of bits per pixel(2 bytes) ms.WriteByte(0x20); ms.WriteByte(0x00); // Compression method(4 bytes) ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); // Image size(4 bytes) ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); // Horizontal resolution of the image(4 bytes) ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); // Vertical resolution of the image(4 bytes) ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); // Number of colors in the color palette(4 bytes) ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); // Number of important colors(4 bytes) ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); ms.WriteByte(0x00); #endregion // Write Bitmap data for (int columnId = height - 1; columnId >= 0; columnId--) { for (int rowId = 0; rowId < width; rowId++) { int pixel = bitmap.Pixels[width * columnId + rowId]; ms.WriteByte((byte)(pixel & 0xff)); //B ms.WriteByte((byte)((pixel >> 8) & 0xff)); //G ms.WriteByte((byte)((pixel >> 0x10) & 0xff)); //R ms.WriteByte(0x00); //reserved } } return new System.IO.MemoryStream(ms.GetBuffer(), true); } }