Create large scale image with scale limitation

My client wants to use GODiagram to create large scale image.
I used

RectangleF rF = new RectangleF(View.DiagramView.Document.TopLeft, View.DiagramView.Document.Size);

Bitmap bmp = View.DiagramView.GetBitmapFromCollection(View.DiagramView.Document, rF, View.DiagramView.DocScale, true);

when View.DiagramView.DocScale=0.048667…,it returns error as

”Parameter is not valid.“

but the scale parameter could be as greater as 1.0. why did It get this error?

I attached the error stacktrack

at System.Drawing.Bitmap…ctor(Int32 width, Int32 height, PixelFormat format)
at System.Drawing.Bitmap…ctor(Int32 width, Int32 height)
at Northwoods.Go.GoView.GetBitmapFromCollection(IGoCollection coll, RectangleF bounds, Single scale, Boolean paper)
at WrmDss.SchematicBuilder.DiagramBuilderViewPresenter.ExportDiagramToImage() in D:\Projects\WRM-DSS\5-Implementation\WrmDss\Source\Modules\SchematicBuilder\SchematicBuilder\Views\DiagramBuilderView\DiagramBuilderViewPresenter.cs:line 1577

Do you know how large the bitmap would have been? It might be too large for GDI+ to handle.

I have tried to increase the scale to 0.0016… I got the bmp size over 800M. would the error caused by the bitmap it too big from GetBitmapFromCollection(…) method?

I also think about another solution about SVG, I read the document of GoUserGuide. it gave very simple exmaple.
I have tested use the following example code to create SVG
// example code for generating SVG:
GoSvgWriter w = new GoSvgWriter();
w.View = GetCurrentGoView();
w.Generate(@“C:\Demo1.svg”);

I have created it, but when I was trying to use code like below:
RectangleF rf1 = View.DiagramView.DocExtent;
rf1 = new RectangleF(View.DiagramView.Document.TopLeft, View.DiagramView.Document.Size);
svgWriter.Generate(rf1, View.DiagramView.DocScale, fileName + “.svg”);

but I got object does not set to instance error.

Is there any example project to give more guide to create SVG?

it has thousands of objects, my client wants to be able to create large scale image for a long time,

I attached one example image which has not been zoomed in yet.

Yes, that sounds like it might be too big for GDI+.

How did you initialize the GoSvgWriter?
What is the actual error? What is the stack trace?

for using GoSvgWriter, I think that I have done something wrong with trying to define my own SVGGenerator. then I commented that code.

Northwoods.Go.Svg.GoSvgWriter svgWriter = new Northwoods.Go.Svg.GoSvgWriter();
Northwoods.Go.Svg.GoSvgGenerator gosvgGen = new GoSvgGenerator();

//svgWriter.AddTransformer(new GeneratorNodeComponent());
svgWriter.View = View.DiagramView;

//View.DiagramView.PrintPreview();
//RectangleF rf = new RectangleF(View.DiagramView.PrintDocumentTopLeft,
// View.DiagramView.PrintDocumentSize);
svgWriter.Generate(fileName + “.svg”);

but after I used the code to generate the SVG file. I got one black eclipse on each of my GoNode that is also the cause why I tried to write GoSVGGenerator. and also the SVG is opened in Internet explorer, but hiding part of in left side.

I wish that I could upload my svg file, but there is no add attachment functionality.


btw, do you have more detailed example project that I could understand better for using GoSVGWriter, and customized GoSVGGenerator.

I think you shouldn’t need to define your own transformer unless you want to modify the behavior of the standard transformers or unless you have overridden Paint. Have you overridden Paint?

But in your code you have commented that out, so it ought to be working OK except maybe for the rendering of those objects covered by the GeneratorNodeComponent.

Out of curiosity, does the SVG render correctly in other SVG viewers?

that is the reason that I want to upload my SVG file then you could see how is has been rendered in internet explorer.

I did overwrite Paint method for NodeComponent which inherits GoNode
. I dont know which part of my overwrite made my SVG file including that black oval. if you could give a clue, it would be appreciated.

public class NodeComponent : GoNode, INodeComponent, IStyleSettings
{
#region Private class

public delegate void TextChanged();

private class NodeLabel : Northwoods.Go.GoText
{
#region Events

public event TextChanged TextChangedEvent;

#endregion

#region Overrides

public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
TextChangedEvent();
}
}

#endregion
}

#endregion

#region Member variables

///


/// the id of the node component that is same as the id of its corresponding business object
///

private Guid m_id = Guid.Empty;
///
/// the type of the node component
///

private ComponentType m_type = ComponentType.Reservoir;
///
/// Component description
///

private string m_typeDesc = CompTypeDescription.Reservoir;
///
/// The shape of the node
///

private GoShape m_shape = null;
///
/// The number label of the node
///

private GoText m_label_number = null;
///
/// The name label of the node
///

private GoText m_label_name = null;
///
/// The port of the node
///

private Port m_port = null;
///
/// the size of node component
///

private SizeF m_size;
///
/// the default scale
///

private float m_scale = 1.0f;
///
/// the style settings of node component
///

private NodeStyleSettings m_styleSettings;

#endregion

#region Constructors

///
/// Default constructor
///

public NodeComponent()
{
Initialize();
}

public NodeComponent(Guid id, float scale)
{
m_id = id;
m_scale = scale;

Initialize();
}

#endregion

#region Private methods

private void Initialize()
{
//the use can select this node
Selectable = true;
// the user can move this node around
Movable = true;
// the user can resize this node
Resizable = true;
// the node is rescalable
AutoRescales = true;
// the node is editable
Editable = true;
// we do not allow users to reshape the node
Reshapable = false;

m_styleSettings = new NodeStyleSettings(Color.White, Color.Black);
}

///
/// Enable the output view for the node
///

///
///
private void OutputView(object sender, EventArgs e)
{
//FormOutputView frmOutputView = new FormOutputView((this.Document as IDiagram).SimulationId, m_id);
//frmOutputView.Show();
IDIContainerService unityService = new DIContainerService();
ISimulation s = (ISimulation)unityService.RootContainer.Resolve(UnityObjects.CurrentScenario);
WrmDss.DomainModel.Interface.IComponent node = (WrmDss.DomainModel.Interface.IComponent)s.GetNode(this.Id);

ResultsViewer.Net.frmViewerMain_GUI frmViewer
= new ResultsViewer.Net.frmViewerMain_GUI(“Historic”, s.Id.ToString(), node.TypeDescription , node.Id.ToString(), node.Name + " " + node.Number.ToString());
frmViewer.ShowDialog();
}

#endregion

#region Overrides

public override void LayoutChildren(GoObject childchanged)
{
if (this.Initializing) return;

base.LayoutChildren(childchanged);

if (m_shape == null || childchanged == null) return;

// put the number label to the center of the node
if (m_label_number == childchanged)
{
m_label_number.SetSpotLocation(GoObject.MiddleCenter, m_shape, GoObject.MiddleCenter);
}

//if (m_label_name == childchanged)
//{
// m_label_name.SetSpotLocation(GoObject.BottomCenter, m_shape, GoObject.TopCenter, 0f, -m_shape.Height / 4);
//}

// put the port to the center of the node
if (m_port == childchanged)
{
PointF c = m_shape.Center;
m_port.SetSpotLocation(GoObject.Middle, c);
}
}

public override void Paint(Graphics g, GoView view)
{
if (m_label_name != null)
{
m_label_name.FontSize = m_shape.Height * 0.28f;
m_label_name.TextColor = m_styleSettings.LabelColor;

switch (m_styleSettings.NameLabelPosition)
{
case LabelPosition.Top:
m_label_name.SetSpotLocation(GoObject.BottomCenter, m_shape, GoObject.TopCenter, 0f, -m_shape.Height / 4);
break;
case LabelPosition.Bottom:
m_label_name.SetSpotLocation(GoObject.TopCenter, m_shape, GoObject.BottomCenter, 0f, m_shape.Height / 4);
break;
case LabelPosition.Left:
m_label_name.SetSpotLocation(GoObject.MiddleRight, m_shape, GoObject.MiddleLeft, -m_shape.Height / 4, 0f);
break;
case LabelPosition.Right:
m_label_name.SetSpotLocation(GoObject.MiddleLeft, m_shape, GoObject.MiddleRight, m_shape.Height / 4, 0f);
break;
}

m_label_name.Paint(g, view);
}

if (m_shape != null)
{
m_shape.BrushColor = m_styleSettings.FillColor;
m_shape.Paint(g, view);
}

if (m_label_number != null)
{
m_label_number.FontSize = m_shape.Height * 0.28f;
m_label_number.TextColor = m_styleSettings.LabelColor;
m_label_number.Paint(g, view);
}

////For debug purpose
//if (m_port != null)
//{
// m_port.PenColor = Color.Black;
// m_port.BrushColor = Color.Transparent;
// m_port.Paint(g, view);
//}
}

protected override RectangleF ComputeBounds()
{
RectangleF rect = new RectangleF(0, 0, 0, 0);

if (m_shape != null && m_label_name != null)
{
rect = RectangleF.Union(m_shape.Bounds, m_label_name.Bounds);
}

return rect;
}

public override GoObject CopyObject(GoCopyDictionary env)
{
NodeComponent node = new NodeComponent(m_id, m_scale);

node.NodeType = m_type;
node.NumberLabel= m_label_number.Text;
node.NameLabel = m_label_name.Text;

node.Center = this.Center;
node.Bounds = this.Bounds;
(node.StyleSettings as NodeStyleSettings).FillColor = m_styleSettings.FillColor;

return node;
}

public override RectangleF ComputeResize(RectangleF origRect, PointF newPoint, int handle, SizeF min, SizeF max, bool reshape)
{
RectangleF bound = m_shape.ComputeResize(m_shape.Bounds, newPoint, handle, min, max, reshape);
m_size.Width = bound.Width;
m_size.Height = bound.Height;

return base.ComputeResize(origRect, newPoint, handle, min, max, reshape);
}

public override ContextMenuStrip GetContextMenuStrip(GoView view)
{
ContextMenuStrip cm = new ContextMenuStrip();
cm.Items.Add(“View model results”, null, new EventHandler(this.OutputView));
return cm;
}

#endregion

#region INodeComponent Members

public Guid Id
{
get { return m_id; }
set { m_id = value; }
}

public ComponentType NodeType
{
get { return m_type; }
set
{
m_type = value;

switch (m_type )
{
case ComponentType.Reservoir:
m_size = new SizeF((float)(90 * 0.7), (float)(50 * 0.7));

m_shape = new GoTriangle();
m_shape.PenColor = Color.Black;

m_typeDesc = CompTypeDescription.Reservoir;
break;
case ComponentType.Irrigation:
m_size = new SizeF((float)(100 * 0.7), (float)(50 * 0.7));

m_shape = new GoRectangle();
m_shape.PenColor = Color.Black;

m_typeDesc = CompTypeDescription.Irrigation;
break;
case ComponentType.MajorWithdrawal:
m_size = new SizeF((float)(70 * 0.7), (float)(50 * 0.7));

m_shape = new GoDrawing(GoFigure.Pentagon);
m_shape.PenColor = Color.Black;

m_typeDesc = CompTypeDescription.MajorWithdrawal;
break;
case ComponentType.Junction:
m_size = new SizeF((float)(50 * 0.7), (float)(50 * 0.7));

m_shape = new GoDrawing(GoFigure.Circle);
m_shape.PenColor = Color.DarkBlue;

m_typeDesc = CompTypeDescription.Junction;
break;
case ComponentType.ControlStructure:
m_size = new SizeF((float)(40 * 0.7), (float)(20 * 0.7));

m_shape = new HalfCircle();
m_shape.Size = Size;
m_shape.PenColor = Color.Black;

m_typeDesc = CompTypeDescription.ControlStructure;
break;
}

this.Initializing = true;

m_shape.PenWidth = m_scale;
m_shape.Size = new SizeF(m_size.Width*m_scale, m_size.Height * m_scale);
m_shape.Selectable = false;
m_shape.Movable = false;
m_shape.Reshapable = false;
Add(m_shape);

m_port = new Port();
m_port.PortObject = m_shape;
m_port.Height = m_size.Height * m_scale; // *0.8f;
m_port.Width = m_size.Width * m_scale; // *0.8f;
Add(m_port);

m_label_number = new GoText();
m_label_number.Movable = false;
m_label_number.Selectable = false;
m_label_number.Editable = false;
m_label_number.AutoRescales = true;
m_label_number.AutoResizes = true;
m_label_number.Alignment = GoObject.Middle;
Add(m_label_number);

m_label_name = new GoText();

m_label_name.Movable = false;
m_label_name.Selectable = true;
m_label_name.Editable = false;
m_label_name.AutoRescales = true;
m_label_name.AutoResizes = true;
m_label_name.Alignment = GoObject.Middle;
Add(m_label_name);

this.Initializing = false;
LayoutChildren(null);
}
}

public string NodeTypeDescription
{
get { return m_typeDesc; }
}

public string NumberLabel
{
get { return m_label_number.Text; }
set
{
m_label_number.Remove();
m_label_number.Text = value;
Add(m_label_number);
}
}

public string NameLabel
{
get { return m_label_name.Text; }
set
{
//m_label_name.Remove();
//m_label_name = value;
//Add(m_label_name);

m_label_name.Text = value;
}
}

public GoShape Shape
{
get { return m_shape; }
}

public GoPort Port
{
get { return m_port; }
set
{
foreach (IGoPort p in this.Ports)
(p as GoPort).Remove();

m_port = (Port)value;
Add(m_port);
}
}

public float Scale
{
get { return m_scale; }
set
{
m_scale = value;

PointF loc = m_shape.Center;

m_shape.Width = m_size.Width * m_scale;
m_shape.Height = m_size.Height * m_scale;
m_shape.PenWidth = m_scale;

m_port.Width = m_size.Width * m_scale; //*0.8f;
m_port.Height = m_size.Height * m_scale; //*0.8f;
m_port.PenWidth = m_scale;

m_shape.Center = loc;
m_port.Center = loc;
}
}

public bool CanBeOutLink(ComponentType linkType)
{
bool result = true;

switch (linkType)
{
case ComponentType.ApportionmentChannel:
result = m_type == ComponentType.Reservoir || m_type == ComponentType.Junction;
break;
case ComponentType.DiversionChannel:
result = m_type == ComponentType.Reservoir || m_type == ComponentType.Junction ||
m_type == ComponentType.Irrigation || m_type == ComponentType.MajorWithdrawal;
break;
case ComponentType.HydroPlant:
//result = m_type == ComponentType.Reservoir;
result = m_type == ComponentType.Reservoir || m_type == ComponentType.Junction ||
m_type == ComponentType.Irrigation || m_type == ComponentType.MajorWithdrawal;
break;
case ComponentType.Inflow:
result = false;
break;
case ComponentType.MinorWithdrawal:
result = m_type == ComponentType.Reservoir || m_type == ComponentType.Junction ||
m_type == ComponentType.MajorWithdrawal || m_type == ComponentType.Irrigation;
break;
case ComponentType.NaturalChannel:
result = m_type == ComponentType.Reservoir || m_type == ComponentType.Junction ||
m_type == ComponentType.Irrigation || m_type == ComponentType.MajorWithdrawal;
break;
case ComponentType.ReturnFlow:
result = m_type == ComponentType.Irrigation || m_type == ComponentType.MajorWithdrawal;
result &= this.DestinationLinks.Count < 5;

break;
}

return result;
}

public bool CanBeInLink(ComponentType linkType)
{
bool result = true;

switch (linkType)
{
case ComponentType.ApportionmentChannel:
result = m_type == ComponentType.Junction;
break;
case ComponentType.DiversionChannel:
result = m_type == ComponentType.Reservoir || m_type == ComponentType.Irrigation ||
m_type == ComponentType.MajorWithdrawal || m_type == ComponentType.Junction;
break;
case ComponentType.HydroPlant:
//result = m_type == ComponentType.Junction || m_type == ComponentType.Reservoir;
result = m_type == ComponentType.Reservoir || m_type == ComponentType.Irrigation ||
m_type == ComponentType.MajorWithdrawal || m_type == ComponentType.Junction;
break;
case ComponentType.Inflow:
result = m_type == ComponentType.Reservoir || m_type == ComponentType.Junction ||
m_type == ComponentType.MajorWithdrawal || m_type == ComponentType.Irrigation;
break;
case ComponentType.MinorWithdrawal:
result = false;
break;
case ComponentType.NaturalChannel:
result = m_type == ComponentType.Reservoir || m_type == ComponentType.Irrigation ||
m_type == ComponentType.MajorWithdrawal || m_type == ComponentType.Junction;
break;
case ComponentType.ReturnFlow:
result = m_type == ComponentType.Reservoir || m_type == ComponentType.Junction ||
m_type == ComponentType.Irrigation || m_type == ComponentType.MajorWithdrawal;

break;
}

//this checks Junction business rule that if they have a outgoing link with ControlStructure enabled
//then they only allow maximum 1 incoming link

//Andy March 20th 2013. based on Kent, we should allow the link created to this Junction node. no matter
//whether there is one or more controlstructure on outLink.
//so, we will commented.
if (m_type == ComponentType.Junction)
{
//bool control = false;
//foreach (GoObject obj in this.DestinationLinks)
//{
// ILinkComponent outLink = obj as ILinkComponent;
// if (outLink.AllowControlStructure)
// {
// control = true;
// break;
// }
//}

//if (control)
// result &= this.SourceLinks.Count < 1;
}

return result;
}

#endregion

#region IStyleSettings Members

public object StyleSettings
{
get { return m_styleSettings; }
set { m_styleSettings = (NodeStyleSettings)value; }
}

#endregion
}

The need to override Paint is really rare. The top of your Paint override looks like initialization that should happen way before you get to Paint. and the other stuff where you are calling Paint on objects should not be necessary.

Get rid of your Paint method completely.

In general, create the GoNodes with their various GoShapes and GoIcons and GoDrawings, etc and let all the GoObjects “Paint” themselves. When you do that, the SVG should work too.