Obtain bounding box of <use> with external reference - dom

I am writing an application that uses D3 to make some SVG charts. This application renders a number of annotations onto the charts.
The annotations appear as icons, so I have made an external XML file containing the icons defined within a <defs> section, and reference them by inserting a <use> element something like this:
<use x="100" y="50" xlink:href="defs.xml#iconname" />
I want to lay out the icons so that they are not overlapping and obscuring each other. In order to find out if they are overlapping, I attempt to obtain their bounding boxes.
My problem is that when I try to obtain the bounding boxes, using either getBBox() or getBoundingClientRect(), the returned rectangles have zero width and zero height.
The following sample illustrates the problem:
a.html:
<?xml version="1.0" standalone="no"?>
<html>
<head></head>
<body>
<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
<use id="used_icon" x="100" y="100" xlink:href="b.xml#test_icon" />
</svg>
<script>
var u = document.getElementById("used_icon");
var rect = u.getBoundingClientRect();
console.log("getBoundingClientRect = %d,%d - %d,%d", rect.left, rect.top, rect.right, rect.bottom);
var box = u.getBBox();
console.log("getBBox = x=%d,y=%d - w=%d,h=%d", box.x, box.y, box.width, box.height);
</script>
</body>
</html>
b.xml
<?xml version="1.0" standalone="no"?>
<svg width="0" height="0" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<g id="test_icon">
<rect width="50" height="50" />
</g>
</defs>
</svg>
The output of this, in both Firefox is:
getBoundingClientRect = 8,8 - 8,8
getBBox = x=0,y=0 - w=0,h=0
and Chrome:
getBoundingClientRect = 107,107 - 107,107
getBBox = x=0,y=0 - w=0,h=0
If I place the <defs> inline in the same document, this does not occur and I get correct width and height (although incorrect x & y in Chrome due to this bug). But I would prefer not to have them in the same document, so that I can centralize the definition of all my icons.
I assume the reason for this is the asynchronous nature of referencing externally definitions - the browser may have to fetch them. Note that the page is constructed dynamically so it is not just a case of waiting until onLoad or similar event is emitted.
Is there any way I can get a callback when the external references have been loaded?

Related

Fixed space between rows in FlexLayout?

FlexLayout adjusts the spacing between the rows of content so the whole of its area is filled:
Can it be set to have no spacing between rows, or a fixed one? So that the rows would be packed to the top of the FlexLayout, and below there would be unused space? I have tried different settings (AlignItems, VerticalOptions, AlignContent) but couldn't achieve the desired result...
P.S.: the elements' size is fixed. These are added programmaticaly.
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp3.ActivitiesPage">
<Grid RowDefinitions="50,*,75" ColumnDefinitions="200, *">
<ScrollView Grid.RowSpan="2" x:Name="ActScroll">
<VerticalStackLayout x:Name="Activities" Padding="5" />
</ScrollView>
<Frame Padding="5" Grid.Column="1">
<Entry x:Name="ActText" BackgroundColor="Grey" />
</Frame>
<FlexLayout Grid.Row="1" Grid.Column="1" x:Name="Picker" Direction="Row" Wrap="Wrap" Padding="5" />
<HorizontalStackLayout Grid.ColumnSpan="2" Grid.Row="2" Padding="5" >
<Button x:Name="btnAdd" Text="Add" Clicked="btnAdd_Clicked" Margin="10"/>
<Button x:Name="btnSave" Text="Save" Margin="10" IsEnabled="False" Clicked="btnSave_Clicked"/>
<Button x:Name="btnDelete" Text="Delete" Margin="10" IsEnabled="False" Clicked="btnDelete_Clicked"/>
</HorizontalStackLayout>
</Grid>
</ContentPage>
Code behind (fragment):
public ActivitiesPage()
{
InitializeComponent();
//color picker
var ActColors = new Color[]
{
Colors.DimGray,
Colors.DarkGray,
Colors.Linen,
Colors.AntiqueWhite,
Colors.PeachPuff,
Colors.Tan,
Colors.BurlyWood,
Colors.SandyBrown,
Colors.Peru,
Colors.Chocolate,
Colors.Firebrick,
Colors.DarkRed,
Colors.Brown,
Colors.IndianRed,
Colors.LightCoral,
Colors.LightPink,
Colors.PaleVioletRed,
Colors.HotPink,
Colors.DeepPink,
Colors.MediumVioletRed,
Colors.DarkMagenta,
Colors.DarkOrchid,
Colors.Orchid,
Colors.MediumPurple,
Colors.BlueViolet,
Colors.DarkSlateBlue,
Colors.RoyalBlue,
Colors.DodgerBlue,
Colors.DeepSkyBlue,
Colors.LightSkyBlue,
Colors.PaleTurquoise,
Colors.Turquoise,
Colors.MediumTurquoise,
Colors.Aqua,
Colors.LightSeaGreen,
Colors.SeaGreen,
Colors.DarkGreen,
Colors.ForestGreen,
Colors.LimeGreen,
Colors.PaleGreen,
Colors.YellowGreen,
Colors.Olive,
Colors.DarkGoldenrod,
Colors.DarkOrange,
Colors.Gold,
Colors.Orange,
Colors.OrangeRed,
Colors.Crimson,
Colors.DarkSalmon,
Colors.Coral,
};
foreach (var col in ActColors)
{
btn.Margin = 2;
btn.MinimumWidthRequest = 50;
btn.MaximumWidthRequest = 50;
btn.MaximumHeightRequest = 50;
btn.MinimumHeightRequest= 50;
btn.FontSize = 12;
btn.CornerRadius = 2;
Picker.Add(btn);
}
}
(this is why, source code goes a long way, when you post question)
Your FlexLayout is solved by:
AlignContent="Start" AlignItems="Start" Direction="Row" Wrap="Wrap"
There is nothing else that is needed to have what you want.
The interesting part is the code that is around this FlexLayout. How will you make sure that it gets its desired Width and Height? Easy way is to set its Width and Height request.
(Good way to write interface, is to set faint background of containers, to watch its borders when you make changes.)
Edit: Tested it:
<FlexLayout x:Name="flex" AlignContent="Start" AlignItems="Start" Direction="Row" Wrap="Wrap" BackgroundColor="AliceBlue" HorizontalOptions="FillAndExpand" HeightRequest="500">
And populated it:
for (int i = 0; i < 100; i++)
{
Button b = new Button();
b.WidthRequest = 25;
b.HeightRequest = 25;
b.Text = i.ToString();
flex.Add(b);
}
Everything is exactly like in your picture.

SVG Showing black color in flutter. Used flutter_svg dependency

I'm trying to render the SVG in the application using flutter_svg: ^0.17.3+1 dependency. It renders the SVG but it is in black color. the same thing happens for all the SVG's.
In the SVG code data-name="Layer 1" showing error attribute data-name is not allowed here.
I search for the answer but I'm unable to find the perfect answer to this. please kindly help me to solve the issue.
//flutter code
Expanded(
child: Container(
child: SvgPicture.asset("assets/svg_arrow.svg"),
),
),
///SVG image code
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 255.32 253.28">
<defs>
<style>.cls-1{fill:#fff;}.cls-2{fill:#a64ac9;}</style>
</defs>
<title>icons</title>
<circle class="cls-1" cx="127.2" cy="125.99" r="123.03" />
<path class="cls-2"
d="M151.85,49.8,84.77,109.23l-9.56,8.46c-3.18,2.82-2.92,8.36,0,11.21L140.81,193l9.42,9.2c7.3,7.13,18.51-4.07,11.2-11.21l-65.6-64.09-9.41-9.2V128.9L153.5,69.47,163.06,61c7.65-6.77-3.59-18-11.21-11.2Z" />
</svg>
Thanks to some user. As per his code. directly add the style tag fill values in path and shape.
This also work for other SVG's.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 255.32 253.28">
<circle cx="127.2" cy="125.99" r="123.03" fill="#fff" />
<path
d="M151.85,49.8,84.77,109.23l-9.56,8.46c-3.18,2.82-2.92,8.36,0,11.21L140.81,193l9.42,9.2c7.3,7.13,18.51-4.07,11.2-11.21l-65.6-64.09-9.41-9.2V128.9L153.5,69.47,163.06,61c7.65-6.77-3.59-18-11.21-11.2Z"
fill="#a64ac9" />
</svg>

Relative path links are not working in iphone

I created an SVG menu for a single page website. When I use the menu from my computer everything works fine, but when I try to access from my phone, the links are not working. I noticed that the issue only happens if I use relative paths (I am only linking to the Id of the element) and with Iphones, I don’t have any issues with Android devices. My problem is that if I use absolute paths, I lose the scroll-behavior animation (smooth).
I don't know if this is issue with my SVG or that I simply can't use relative path in iphones.
This is the link for my project: http://portfolio-2019-cg.herokuapp.com
I am using React to create this website.
<div>
<svg className="circle" width="611px" onClick={this.showMenu} height="883px" viewBox="0 0 611 883" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
<path id='menu' className={this.state.activeclass} d="M611,473 L611,708 C611,804.649831 532.649831,883 436,883 L269,883 L60,883 C26.862915,883 1.11635499e-14,856.137085 7.10542736e-15,823 L1.08387875e-15,473 L-1.42108547e-14,60 C-1.82689772e-14,26.862915 26.862915,6.08718376e-15 60,0 L551,0 C584.137085,-6.08718376e-15 611,26.862915 611,60 L611,473 Z" id="Combined-Shape" fill="#FF531B"></path>
<circle id="Oval" fill="#FF531B" cx="436" cy="708" r="175"></circle>
<path className={this.state.plusclass} onClick={this.showMenu} d="M486,658.5 L561.5,658.5 L561.5,758.5 L486,758.5 L486,834 L386,834 L386,758.5 L310.5,758.5 L310.5,658.5 L386,658.5 L386,583 L486,583 L486,658.5 Z" id="Combined-Shape" fill="#080815"></path>
<g className={this.state.menuclass}>
<text id="HOME" fontSize="94" fontWeight="normal" fill="#080815">
<a xlinkHref="#home">
<tspan x="205.181641" y="140">Home</tspan>
</a>
</text>
<text id="ABOUT" fontSize="94" fontWeight="normal" fill="#080815">
<a xlinkHref="#about">
<tspan x="176.977051" y="270">About</tspan>
</a>
</text>
<text id="PORTFOLIO" fontSize="94" fontWeight="normal" fill="#080815">
<a xlinkHref="#portfolio">
<tspan x="64.1586914" y="400">Portfolio</tspan>
</a>
</text>
<text id="CONTACT" fontSize="94" fontWeight="normal" fill="#080815">
<a xlinkHref="#contact">
<tspan x="120.567871" y="530">Contact</tspan>
</a>
</text>
</g>
</g>
</svg>
</div>

Flex formitem label aligment oddity

I have paid a decent hair tribute to this one
Why in the world, Label 1 and Label 2 have different vertical alignments?
<s:Form width="100%">
<s:FormHeading width="100%" label="Heading" />
<s:FormItem width="100%" label="Label 1">
<s:HGroup verticalAlign="bottom">
<s:Label text="Size" fontSize="40"/>
<s:Label text="Mb"/>
</s:HGroup>
</s:FormItem>
<s:FormItem width="100%" label="Label 2">
<s:HGroup verticalAlign="middle">
<s:VGroup horizontalAlign="center">
<s:Label text="Set1" />
<s:Label text="{this.set1}" fontSize="40"/>
<s:Label text="Days" />
</s:VGroup>
<s:Label text="+" fontSize="40" />
<s:VGroup horizontalAlign="center">
<s:Label text="Set2" />
<s:Label text="{this.set2}" fontSize="40" />
<s:Label text="Days" />
</s:VGroup>
</s:HGroup>
</s:FormItem>
</s:Form>
Bug or feature? The label of a FormItem is aligned with the baseline of the FormItem's content. A picture says more than a thousand words, so I'll show you what happens:
So it turns out to be a feature (thanks for asking this question: I didn't know this myself until today).
In order to "fix" this feature, you'll have to create a custom skin: create a skin class by copying the original spark.skins.spark.FormItemSkin.
Find the element called labelDisplay; it should look like this:
<s:Label id="labelDisplay"
fontWeight="bold"
left="labelCol:0" right="labelCol:5"
bottom="row1:10" baseline="row1:0"/>
See that baseline attribute? That's what's causing the undesired behaviour.
You can simply remove it; the label will then always align to the bottom. If you wish to align it to the vertical center, you could alter it like this:
<s:Label id="labelDisplay" fontWeight="bold" verticalAlign="middle"
left="labelCol:0" right="labelCol:5" top="row1:10" bottom="row1:10"/>
Now all you need to do, is applying your custom skin to your FormItem:
<s:FormItem skinClass="my.custom.FormItemSkin">
Or in case of more frequent usage:
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
s|FormItem.centeredLabel {
skinClass: ClassReference("my.custom.FormItemSkin");
}
</fx:Style>
<s:FormItem styleName="centeredLabel">

basic grid in gwt sencha uibinder not working

I am trying to make a basic grid in GWT Sencha.
it works fine , but i am not sure how to put the grid in UiBinder ,
Not sure what would be the parent widget ,
thats what i am doing
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<c:FramedPanel>
<grid:GridView ui:field="gridMain">
</grid:GridView>
</c:FramedPanel>
Error:
Expected a widget or <g:cell>, found <grid:GridView ui:field='gridMain'> Element <g:VerticalPanel> (:4
Add the following line in ui.xml
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:grid="urn:import:Package-of-GridView">
If you have already added these two lines then its fine
Here is my question and answer for you.
I guess GridView is your view class. Is it extends any widgets?
If it extends any widgets then it will work. If not it just a class.
We can add a widget in a widget but we can't add a class in a widget.
So if required extend the appropriate widget to GridView
For eg. public class Gridview extends VerticalPanel
The UIBinder examples for gxt can be found here:
http://gxt-uibinder.appspot.com/
This is specifically the example you're looking for:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:gxt="urn:import:com.extjs.gxt.ui.client.widget" xmlns:toolbar="urn:import:com.extjs.gxt.ui.client.widget.toolbar" xmlns:form="urn:import:com.extjs.gxt.ui.client.widget.form" xmlns:grid="urn:import:com.extjs.gxt.ui.client.widget.grid">
<ui:with type="com.jhickman.web.gwt.gxtuibindertest.client.resources.icons.ExampleIcons" field="icons" />
<ui:with type="com.extjs.gxt.ui.client.store.ListStore" field="store" />
<ui:with type="com.google.gwt.i18n.client.DateTimeFormat" field="dateformat" />
<ui:with type="com.jhickman.web.gwt.gxtuibindertest.client.view.grids.BasicGridView.ChangeCellRenderer" field="change" />
<ui:with type="com.jhickman.web.gwt.gxtuibindertest.client.view.grids.BasicGridView.GridNumberRenderer" field="gridNumber" />
<gxt:LayoutContainer layout="FlowLayout">
<gxt:layoutdata type="FlowData" margins="10">
<gxt:ContentPanel bodyBorder="true" icon="{icons.table}" heading="Basic Grid" buttonAlign="CENTER" layout="FitLayout" width="600" height="300">
<gxt:topcomponent>
<toolbar:ToolBar>
<toolbar:LabelToolItem label="Selection Mode:" />
<form:SimpleComboBox triggerAction="ALL" editable="false" fireChangeEventOnSetValue="true" width="100" ui:field="selectionModeComboBox" />
</toolbar:ToolBar>
</gxt:topcomponent>
<grid:Grid store="{store}"
ui:field="grid"
styleAttribute="borderTop:none"
autoExpandColumn="name"
borders="false"
stripeRows="true"
columnLines="true"
columnReordering="true">
<grid:column id="name"
header="Company"
width="200"
rowHeader="true" />
<grid:column id="symbol"
header="Symbol"
width="100" />
<grid:column id="last"
header="Last"
alignment="RIGHT"
width="75"
renderer="{gridNumber}"/>
<grid:column id="change"
header="Change"
width="100"
alignment="RIGHT"
renderer="{change}" />
<grid:column id="date"
header="Last Updated"
width="100"
alignment="RIGHT"
dateTimeFormat="{dateformat}" />
</grid:Grid>
</gxt:ContentPanel>
</gxt:layoutdata>
</gxt:LayoutContainer>
</ui:UiBinder>
You can't directly add grid under FramedPanel
Try to add a container such as VerticalLayoutContainer as a child of your FramedPanel before adding the grid.
in UiBinder
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:gxt="urn:import:com.sencha.gxt.widget.core.client"
xmlns:row="urn:import:com.sencha.gxt.widget.core.client.container">
Under your FramedPanel
<gxt:FramedPanel ui:field="panel" headingText="VerticalLayout Example"
collapsible="false">
<row:VerticalLayoutContainer>
<row:child><grid:GridView ui:field="view"></grid:GridView>
</row:child>
<row:VerticalLayoutContainer>