SetGraphScale() public method

public SetGraphScale ( Int32 bitmapWidthPx, Int32 bitmapHeightPx, Double screenDpi ) : void
bitmapWidthPx System.Int32
bitmapHeightPx System.Int32
screenDpi Double
return void
    Composite
    (
        Double compositeWidth,
        Double compositeHeight,
        String headerText,
        String footerText,
        System.Drawing.Font headerFooterFont,
        IEnumerable<LegendControlBase> legendControls
    )
    {
        Debug.Assert(compositeWidth > 0);
        Debug.Assert(compositeHeight > 0);
        Debug.Assert(headerFooterFont != null);
        Debug.Assert(legendControls != null);
        AssertValid();

        // Note:
        //
        // Don't try taking a shortcut by using
        // NodeXLControl.CopyGraphToBitmap() to get an image of the graph and
        // then compositing the image with the other elements.  That would work
        // if the caller were creating an image, but if it were creating an XPS
        // document, the graph would no longer be scalable.

        Double dScreenDpi =
            WpfGraphicsUtil.GetScreenDpi(m_oNodeXLControl).Width;

        // The NodeXLControl can't be a child of two logical trees, so
        // disconnect it from its parent after saving the current vertex
        // locations.

        m_oLayoutSaver = new LayoutSaver(m_oNodeXLControl.Graph);

        Debug.Assert(m_oNodeXLControl.Parent is Panel);
        m_oParentPanel = (Panel)m_oNodeXLControl.Parent;
        UIElementCollection oParentChildren = m_oParentPanel.Children;
        m_iChildIndex = oParentChildren.IndexOf(m_oNodeXLControl);
        oParentChildren.Remove(m_oNodeXLControl);

        m_oGraphImageScaler = new GraphImageScaler(m_oNodeXLControl);

        m_oGraphImageCenterer = new NodeXLControl.GraphImageCenterer(
            m_oNodeXLControl);

        // The header and footer are rendered as Label controls.  The legend is
        // rendered as a set of Image controls.

        Label oHeaderLabel, oFooterLabel;
        IEnumerable<Image> oLegendImages;
        Double dHeaderHeight, dTotalLegendHeight, dFooterHeight;

        CreateHeaderOrFooterLabel(headerText, compositeWidth, headerFooterFont,
            out oHeaderLabel, out dHeaderHeight);

        CreateLegendImages(legendControls, compositeWidth, out oLegendImages,
            out dTotalLegendHeight);

        CreateHeaderOrFooterLabel(footerText, compositeWidth, headerFooterFont,
            out oFooterLabel, out dFooterHeight);

        m_oNodeXLControl.Width = compositeWidth;

        m_oNodeXLControl.Height = Math.Max(10,
            compositeHeight - dHeaderHeight - dTotalLegendHeight
            - dFooterHeight);

        // Adjust the control's graph scale so that the graph's vertices and
        // edges will be the same relative size in the composite that they are
        // in the control.

        m_oGraphImageScaler.SetGraphScale(
            (Int32)WpfGraphicsUtil.WpfToPx(compositeWidth, dScreenDpi),
            (Int32)WpfGraphicsUtil.WpfToPx(m_oNodeXLControl.Height, dScreenDpi),
            dScreenDpi);

        // Adjust the NodeXLControl's translate transforms so that the
        // composite will be centered on the same point on the graph that the
        // NodeXLControl is centered on.

        m_oGraphImageCenterer.CenterGraphImage( new Size(compositeWidth,
            m_oNodeXLControl.Height) );

        StackPanel oStackPanel = new StackPanel();
        UIElementCollection oStackPanelChildren = oStackPanel.Children;

        // To avoid a solid black line at the bottom of the header or the top
        // of the footer, which is caused by rounding errors, make the
        // StackPanel background color the same as the header and footer.

        oStackPanel.Background = HeaderFooterBackgroundBrush;

        if (oHeaderLabel != null)
        {
            oStackPanelChildren.Add(oHeaderLabel);
        }

        // Wrap the NodeXLControl in a Grid to clip it.

        m_oGrid = new Grid();
        m_oGrid.Width = m_oNodeXLControl.Width;
        m_oGrid.Height = m_oNodeXLControl.Height;
        m_oGrid.ClipToBounds = true;
        m_oGrid.Children.Add(m_oNodeXLControl);

        oStackPanelChildren.Add(m_oGrid);

        foreach (Image oLegendImage in oLegendImages)
        {
            oStackPanelChildren.Add(oLegendImage);
        }

        if (oFooterLabel != null)
        {
            oStackPanelChildren.Add(oFooterLabel);
        }

        Size oCompositeSize = new Size(compositeWidth, compositeHeight);
        Rect oCompositeRectangle = new Rect(new Point(), oCompositeSize);

        oStackPanel.Measure(oCompositeSize);
        oStackPanel.Arrange(oCompositeRectangle);
        oStackPanel.UpdateLayout();

        return (oStackPanel);
    }
Ejemplo n.º 2
0
    CopyGraphToBitmap
    (
        Int32 bitmapWidthPx,
        Int32 bitmapHeightPx
    )
    {
        const String MethodName = "CopyGraphToBitmap";

        this.ArgumentChecker.CheckArgumentPositive(MethodName, "bitmapWidthPx",
            bitmapWidthPx);

        this.ArgumentChecker.CheckArgumentPositive(MethodName, "bitmapHeightPx",
            bitmapHeightPx);

        CheckIfLayingOutGraph(MethodName);

        // Save the current vertex locations.

        LayoutSaver oLayoutSaver = new LayoutSaver(this.Graph);

        // Adjust the control's graph scale so that the graph's vertices and
        // edges will be the same relative size in the image that they are in
        // the control.

        GraphImageScaler oGraphImageScaler = new GraphImageScaler(this);

        oGraphImageScaler.SetGraphScale(bitmapWidthPx, bitmapHeightPx,
            WpfGraphicsUtil.GetScreenDpi(this).Width);

        // Adjust the control's transforms so that the image will be centered
        // on the same point on the graph that the control is centered on.

        GraphImageCenterer oGraphImageCenterer = new GraphImageCenterer(this);

        oGraphImageCenterer.CenterGraphImage(
            new Size(bitmapWidthPx, bitmapHeightPx) );

        // Transform the graph's layout to the specified size.

        Double dOriginalActualWidth = this.ActualWidth;
        Double dOriginalActualHeight = this.ActualHeight;

        Rect oBitmapRectangle = new Rect(0, 0,
            (Double)bitmapWidthPx, (Double)bitmapHeightPx);

        TransformLayout(oBitmapRectangle);

        Debug.Assert(m_eLayoutState == LayoutState.Stable);

        DrawGraph(oBitmapRectangle);

        System.Drawing.Bitmap oBitmap = WpfGraphicsUtil.VisualToBitmap(this,
            bitmapWidthPx, bitmapHeightPx);

        // Restore the original layout.
        //
        // NOTE:
        //
        // Don't try calling TransformLayout() again using the original
        // rectangle.  The first call to TransformLayout() lost "resolution" if
        // the layout was transformed to a smaller rectangle, and attempting to
        // reverse the transform will yield poor results.

        oLayoutSaver.RestoreLayout();

        oGraphImageScaler.RestoreGraphScale();

        oBitmapRectangle =
            new Rect(0, 0, dOriginalActualWidth, dOriginalActualHeight);

        Debug.Assert(m_eLayoutState == LayoutState.Stable);

        DrawGraph(oBitmapRectangle);

        oGraphImageCenterer.RestoreCenter();

        return (oBitmap);
    }