I am using d3-svg-legend ( https://d3-legend.susielu.com/) to create a legend based on size. I want to replicate this example: https://d3-legend.susielu.com/#size-line
The code I am using is:
let svg = d3.select(this.refs.canvas).append('svg');
const g = svg.append("g");
var lineSize = d3.scaleLinear().domain([0,10]).range([2, 10]);
g.attr("transform", "translate(20,20)")
.call(legendSize()
.scale(lineSize)
.shape("line")
.orient("horizontal")
.shapeWidth(40)
.labelAlign("start")
.shapePadding(10)
);
This code produces the following output:
<div style="margin-left: auto; margin-right: 20px;">
<svg>
<g transform="translate(20,20)">
<g class="legendCells"><g class="cell" transform="translate(0, 5)">
<line class="swatch" x1="0" x2="40" y1="0" y2="0" stroke-width="2" style="fill: rgb(153, 216, 201);"></line>
<text class="label" transform="translate( 0,15)" style="text-anchor: start;">0.0</text></g><g class="cell" transform="translate(50, 5)">
<line class="swatch" x1="0" x2="40" y1="0" y2="0" stroke-width="4" style="fill: rgb(211, 74, 65);"></line>
<text class="label" transform="translate( 0,15)" style="text-anchor: start;">2.5</text>
</g>
<g class="cell" transform="translate(100, 5)">
<line class="swatch" x1="0" x2="40" y1="0" y2="0" stroke-width="6" style="fill: rgb(255, 0, 0);"></line>
<text class="label" transform="translate( 0,15)" style="text-anchor: start;">5.0</text>
</g>
<g class="cell" transform="translate(150, 5)">
<line class="swatch" x1="0" x2="40" y1="0" y2="0" stroke-width="8" style="fill: rgb(255, 0, 0);"></line>
<text class="label" transform="translate( 0,15)" style="text-anchor: start;">7.5</text>
</g>
<g class="cell" transform="translate(200, 5)">
<line class="swatch" x1="0" x2="40" y1="0" y2="0" stroke-width="10" style="fill: rgb(255, 0, 0);"></line>
<text class="label" transform="translate( 0,15)" style="text-anchor: start;">10.0</text>
</g>
</g>
</g>
</svg>
</div>
But it doesn't display any legend other than the labels (i.e. it doesn't display the line elements):
If you look at the same example, you'll see that she's setting the stroke using a <style> tag in the <head>:
.legendSizeLine line {
stroke: rgb(46, 73, 123);
}
That's necessary because the default <line> stroke is "none".
Here is your SVG with that style:
line {
stroke: rgb(46, 73, 123);
}
text {
font: 12px sans-serif;
}
<div style="margin-left: auto; margin-right: 20px;">
<svg>
<g transform="translate(20,20)">
<g class="legendCells">
<g class="cell" transform="translate(0, 5)">
<line class="swatch" x1="0" x2="40" y1="0" y2="0" stroke-width="2" style="fill: rgb(153, 216, 201);"></line>
<text class="label" transform="translate( 0,15)" style="text-anchor: start;">0.0</text>
</g>
<g class="cell" transform="translate(50, 5)">
<line class="swatch" x1="0" x2="40" y1="0" y2="0" stroke-width="4" style="fill: rgb(211, 74, 65);"></line>
<text class="label" transform="translate( 0,15)" style="text-anchor: start;">2.5</text>
</g>
<g class="cell" transform="translate(100, 5)">
<line class="swatch" x1="0" x2="40" y1="0" y2="0" stroke-width="6" style="fill: rgb(255, 0, 0);"></line>
<text class="label" transform="translate( 0,15)" style="text-anchor: start;">5.0</text>
</g>
<g class="cell" transform="translate(150, 5)">
<line class="swatch" x1="0" x2="40" y1="0" y2="0" stroke-width="8" style="fill: rgb(255, 0, 0);"></line>
<text class="label" transform="translate( 0,15)" style="text-anchor: start;">7.5</text>
</g>
<g class="cell" transform="translate(200, 5)">
<line class="swatch" x1="0" x2="40" y1="0" y2="0" stroke-width="10" style="fill: rgb(255, 0, 0);"></line>
<text class="label" transform="translate( 0,15)" style="text-anchor: start;">10.0</text>
</g>
</g>
</g>
</svg>
</div>
Related
below i create a simple fiddle with svg animation:
<svg width="250" height="250" viewbox="0 0 20 20">
<line x1="10" y1="0" x2="10" y2="10"style="stroke:rgb(255,0,0); stroke-width:1">
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 10 10" to="360 10 10" dur="7.5s" repeatCount="indefinite" />
</line>
<circle cx="5" cy="5" r="1" style="fill:rgb(0,255,0);"/>
<circle cx="15" cy="15" r="1" style="fill:rgb(0,0,255);"/>
</svg>
My question is: is there a way that I can make blue and red point bump (change their color for example) when red line hover them?
Thank you
This is my solution: I'm creating a mask with the line. There are 2 extra circles (fill:gold) that are masked by the line.
I'm putting the animated line inside a <g stroke="red"> because I want the used line to be white.
svg{border:1px solid;}
<svg width="250" height="250" viewbox="0 0 20 20">
<circle cx="5" cy="5" r="1" style="fill:rgb(0,255,0);" />
<circle cx="15" cy="15" r="1" style="fill:rgb(0,0,255);"/>
<mask id="mask">
<use xlink:href="#L" style="stroke:white"/>
</mask>
<g stroke="red">
<line id="L" x1="10" y1="0" x2="10" y2="10" >
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 10 10" to="360 10 10" dur="7.5s" repeatCount="indefinite" />
</line>
</g>
<g style="fill:gold;mask: url(#mask)">
<circle cx="5" cy="5" r="1" />
<circle cx="15" cy="15" r="1"/>
</g>
</svg>
I have a use case where I have to load a hash pattern inside an svg.
So since, its a graph we are using inner elements as group elements like this.
<svg>
... ... ...
<g class="random-data-task" aria-selected="false" aria-describedby="task3">
<defs>
<pattern id="pattern-stripe" patternUnits="userSpaceOnUse" patternTransform="rotate(45)" width="2" height="23">
<rect width="341.33333333333337" height="23" style="fill: #fff;" x="153.6217133163698" y="50"></rect>
</pattern>
</defs>
<rect x="153.6217133163698" y="50" width="341.33333333333337" height="23" class="random-data-bar" style="fill: #f4f4f4;"></rect>
<rect x="153.6217133163698" y="50" width="341.33333333333337" height="23" class="random-data-bar" style="fill: url(#pattern-stripe); stroke: #f4f4f4; opacity: 1;"></rect>
</g>
... ... ... </svg>
So, while doing this, the pattern is not visible.
But when I try to use an svg and make each rect (bar) as svg, I'm able to see the pattern I want, but this won't re-scale my bars when I zoom in or out, since its going to rendered in a time-range.
<svg>
... ... ...
<svg class="random-data-task" aria-selected="false" aria-describedby="task3">
<defs>
<pattern id="pattern-stripe" patternUnits="userSpaceOnUse" patternTransform="rotate(45)" width="2" height="23">
<rect width="341.33333333333337" height="23" style="fill: #fff;" x="153.6217133163698" y="50"></rect>
</pattern>
</defs>
<rect x="153.6217133163698" y="50" width="341.33333333333337" height="23" class="random-data-bar" style="fill: #f4f4f4;"></rect>
<rect x="153.6217133163698" y="50" width="341.33333333333337" height="23" class="random-data-bar" style="fill: url(#pattern-stripe); stroke: #f4f4f4; opacity: 1;"></rect>
</svg>
... ... ...
here is the code for my hash bars looks like
const renderHashedBarGroup = (scale, taskData, taskPath) => {
const _args = generatorArgs(scale, taskData, taskPath);
(taskData.isBackGround ? getBackgroundHashedBar : getForeGroundHashedBar)(
_args.path.append("defs"),
_args.path,
_args.x,
_args.y,
_args.width,
_args.height,
taskData.isBackGround ? "#d3d4d5" : "#f4f4f4"
);};
const getBackgroundHashedBar = (defs, path, x, y, width, height, color) => {
const patternId = "pattern-stripe-background";
if (d3.select(`#${patternId}`).empty()) {
defs.append("pattern")
.attr("id", patternId)
.attr("patternUnits", "userSpaceOnUse")
.attr("patternTransform", "rotate(135)")
.attr("width", "7")
.attr("height", height)
.append("rect")
.attr("width", "2")
.attr("height", height)
.attr("style", "fill: #fff;");
}
// Draw the background rect
getRect(path, x, y, width, height)
.classed(styles.taskBar, true)
.attr("style", `fill: ${color}; stroke: ${color}; opacity: 0.3`);
// Opacity for bar with hashes
getRect(path, x, y, width, height)
.classed(styles.taskBar, true)
.attr("style", `fill: url(#${patternId}); opacity: 0.7;`);
return path; };
const drawTasks = (scale, config, trackLabel, taskGroupPath, tasks) => {
const taskPath = taskGroupPath
.selectAll("g")
.data(
tasks.map((a) =>
processTask(config, trackLabel, utils.deepClone(a))
)
);
taskPath
.enter()
.append("g")
.classed(styles.task, true)
.attr("aria-selected", false)
.attr("aria-describedby", (d) => d.key)
.each(function(d) {
d.percentage
? renderPercentageBarGroup(scale, d, this)
: d.hasOwnProperty("isHashed") && d.isHashed
? renderHashedBarGroup(scale, d, this)
: renderBarGroup(scale, d, this);
});
taskPath
.exit()
.transition(constants.d3Transition)
.remove();
};
If you don't understand what is happening first remove all that complicates the stuff. Here it is the rotation and almost all colors used are nearly white.
Even setting the rotation to 0 and colors to bright contrasty values we do not see any pattern.
The reason is that the pattern repeats every 2 pixels `width="2"
<pattern id="pattern-stripe" patternUnits="userSpaceOnUse"
patternTransform="rotate(0)" width="2" height="23">
But only at x=153 something is defined in the pattern
<rect width="341" height="23" style="fill: #fff;" x="153" y="50"></rect>
Result you don't see a thing.
If you set the width to a larger value then the x coord of your pattern rect you see in both cases a pattern.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<svg width="700" height="100">
<defs>
<pattern id="pattern-stripe" patternUnits="userSpaceOnUse" patternTransform="rotate(45)" width="200" height="23">
<rect width="341" height="23" fill="yellow" x="153" y="0"></rect>
</pattern>
</defs>
<g class="random-data-task" aria-selected="false" aria-describedby="task3">
<rect x="53" y="50" width="341" height="23" class="random-data-bar" style="fill: #f40000;"></rect>
<rect x="53" y="50" width="341" height="23" class="random-data-bar" fill="url(#pattern-stripe)" style="stroke: #00f400; opacity: 1;"></rect>
</g>
</svg>
<hr/>
<svg width="700" height="100">
<svg>
<defs>
<pattern id="pattern-stripe2" patternUnits="userSpaceOnUse" patternTransform="rotate(45)" width="200" height="23">
<rect width="41" height="23" fill="lime" x="153" y="0"></rect>
</pattern>
</defs>
<rect x="53" y="50" width="341" height="23" class="random-data-bar" style="fill: #0000f4;"></rect>
<rect x="53" y="50" width="341" height="23" class="random-data-bar" fill="url(#pattern-stripe2)" style="stroke: steelblue; opacity: 1;"></rect>
</svg>
</svg>
<hr/>
<p>From code inspection, what is wanted</p>
<svg width="700" height="100">
<defs>
<pattern id="pattern-stripe3" patternUnits="userSpaceOnUse" patternTransform="rotate(135)" width="7" height="23">
<rect width="2" height="23" fill="yellow" x="0" y="0"></rect>
</pattern>
</defs>
<g class="random-data-task" aria-selected="false" aria-describedby="task3">
<rect x="53" y="50" width="341" height="23" class="random-data-bar" style="fill: #f40000;"></rect>
<rect x="53" y="50" width="341" height="23" class="random-data-bar" fill="url(#pattern-stripe3)" style="stroke: #00f400; opacity: 1;"></rect>
</g>
</svg>
<hr/>
<p>With a single rect that has a pattern</p>
<svg width="700" height="100">
<defs>
<pattern id="pattern-stripe4" patternUnits="userSpaceOnUse" patternTransform="rotate(135)" width="7" height="23">
<rect width="2" height="23" fill="yellow" x="0" y="0"></rect>
<rect width="5" height="23" fill="red" x="2" y="0"></rect>
</pattern>
</defs>
<g class="random-data-task" aria-selected="false" aria-describedby="task3">
<rect x="53" y="50" width="341" height="23" class="random-data-bar" fill="url(#pattern-stripe4)" style="stroke: #00f400; opacity: 1;"></rect>
</g>
</svg>
</body>
</html>
What exactly do you want to show/visualize with this overlay pattern?
Edit
I have added a shape based on the widths from your code and a shape with the same look but made with one rect with a pattern.
<svg width="700" height="300">
<defs>
<pattern id="pattern-stripe4" patternUnits="userSpaceOnUse" patternTransform="rotate(135)" width="7" height="23">
<rect width="2" height="23" fill="yellow" x="0" y="0"></rect>
<rect width="5" height="23" fill="red" x="2" y="0"></rect>
</pattern>
</defs>
<g class="random-data-task" aria-selected="false" aria-describedby="task3">
<rect x="53" y="50" width="341" height="23" class="random-data-bar" fill="url(#pattern-stripe4)" style="stroke: #00f400; opacity: 1;"></rect>
</g>
</svg>
To prevent the modification of the pattern rects:
do not select rects without a class designation, the rects in the pattern are also selected and updated
select rect based on class or as sub elements of a particular group
For axample
svg.selectAll(".bars")......
svg.select(".bargroup").selectAll("rect").....
I have a page to tests that has objects, SVG, that are added after a click.
This is like:
startbox (added by default)
then we can added more obejcts that will be connected by a “brick-connector” (line)
When added, it is created, dynamically a < g > and inside a < svg >, like:
<g _ngcontent-c6="" nea-sequence-editor-brick-connector="" _nghost-c8="" ng-reflect-brick-connector="[object Object]"><polyline _ngcontent-c8="" class="line strok1" points="160,120 160,170" style="stroke: rgb(128, 128, 128);"></polyline><polyline _ngcontent-c8="" class="line strok18" points="160,120 160,170" style="stroke: transparent;"></polyline><polygon _ngcontent-c8="" class="line strok1" points="155,165 160,170 165,165" style="stroke: rgb(128, 128, 128); fill: rgb(128, 128, 128);"></polygon></g>
<g _ngcontent-c6="" nea-sequence-editor-brick-connector="" _nghost-c8="" ng-reflect-brick-connector="[object Object]"><polyline _ngcontent-c8="" class="line strok1" points="160,370 160,410" style="stroke: rgb(128, 128, 128);"></polyline><polyline _ngcontent-c8="" class="line strok18" points="160,370 160,410" style="stroke: transparent;"></polyline><polygon _ngcontent-c8="" class="line strok1" points="155,405 160,410 165,405" style="stroke: rgb(128, 128, 128); fill: rgb(128, 128, 128);"></polygon></g>
<g _ngcontent-c6="" nea-sequence-editor-brick="" _nghost-c9="" ng-reflect-item="[object Object]"><!--bindings={
"ng-reflect-ng-if": "true"
}--><svg _ngcontent-c9="" class="nea-svg" x="110" y="20" width="100" height="100" style=""><rect _ngcontent-c9="" class="nea-svg-rect" fill="green" rx="25" ry="25" x="1" y="1" width="98" height="98"></rect><svg _ngcontent-c9="" height="200" width="200"><text _ngcontent-c9="" fill="white" style="font-size:14px" x="25" y="50">START</text></svg><circle _ngcontent-c9="" class="nea-svg-rect-circle" cx="50" cy="100" r="10"></circle></svg><!--bindings={
"ng-reflect-ng-if": "false"
}--></g>
<g _ngcontent-c6="" nea-sequence-editor-brick="" _nghost-c9="" ng-reflect-item="[object Object]"><!--bindings={
"ng-reflect-ng-if": "false"
}--><!--bindings={
"ng-reflect-ng-if": "true"
}--><svg _ngcontent-c9="" class="nea-svg" x="60" y="170" width="200" height="200"><rect _ngcontent-c9="" class="nea-svg-rect" rx="10" ry="10" ng-reflect-ng-style="[object Object]" x="1" y="1" width="198" height="198" style="stroke: rgba(85, 68, 153, 0.867); stroke-width: 4; fill: rgb(0, 114, 187);"></rect><text _ngcontent-c9="" fill="#fff" style="cursor:pointer" x="180" y="20">x</text><text _ngcontent-c9="" fill="white" style="font-size: 14px" x="10" y="20">System: AnalyseErrors</text><line _ngcontent-c9="" x1="2" x2="198" y1="30" y2="30" ng-reflect-ng-style="[object Object]" style="stroke: rgba(85, 68, 153, 0.867); stroke-width: 4;"></line><svg _ngcontent-c9="" class="nea-svg-rect-arg" height="200" width="200"><text _ngcontent-c9="" fill="white" style="font-size:14px" x="130" y="50">Result1</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="50">Parameter 1 </text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="130" y="70">6</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="70">Parameter 2: </text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="130" y="90">10</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="90">Parameter 3: </text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="130" y="110">left</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="110">Parmeter 4: </text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="130" y="135">Result3</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="135">Result : </text></svg><line _ngcontent-c9="" x1="2" x2="198" y1="145" y2="145" ng-reflect-ng-style="[object Object]" style="stroke: rgba(85, 68, 153, 0.867); stroke-width: 4;"></line><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="165">test</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="185">res2</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="50" y="185">=</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="65" y="185">10</text><circle _ngcontent-c9="" class="nea-svg-rect-circle" cx="100" cy="200" r="10"></circle></svg></g>
<g _ngcontent-c6="" nea-sequence-editor-brick="" _nghost-c9="" ng-reflect-item="[object Object]"><!--bindings={
"ng-reflect-ng-if": "false"
}--><!--bindings={
"ng-reflect-ng-if": "true"
}--><svg _ngcontent-c9="" class="nea-svg" x="60" y="410" width="200" height="200"><rect _ngcontent-c9="" class="nea-svg-rect" rx="10" ry="10" ng-reflect-ng-style="[object Object]" x="1" y="1" width="198" height="198" style="stroke: rgba(85, 68, 153, 0.867); stroke-width: 4; fill: rgb(0, 114, 187);"></rect><text _ngcontent-c9="" fill="#fff" style="cursor:pointer" x="180" y="20">x</text><text _ngcontent-c9="" fill="white" style="font-size: 14px" x="10" y="20">System: CheckAbortCycle</text><line _ngcontent-c9="" x1="2" x2="198" y1="30" y2="30" ng-reflect-ng-style="[object Object]" style="stroke: rgba(85, 68, 153, 0.867); stroke-width: 4;"></line><svg _ngcontent-c9="" class="nea-svg-rect-arg" height="200" width="200"><text _ngcontent-c9="" fill="white" style="font-size:14px" x="130" y="50">Result1</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="50">Parameter 1 </text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="130" y="70">6</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="70">Parameter 2: </text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="130" y="90">10</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="90">Parameter 3: </text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="130" y="110">left</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="110">Parmeter 4: </text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="130" y="135">Result3</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="135">Result : </text></svg><line _ngcontent-c9="" x1="2" x2="198" y1="145" y2="145" ng-reflect-ng-style="[object Object]" style="stroke: rgba(85, 68, 153, 0.867); stroke-width: 4;"></line><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="165">test</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="10" y="185">res2</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="50" y="185">=</text><text _ngcontent-c9="" fill="white" style="font-size:14px" x="65" y="185">10</text><circle _ngcontent-c9="" class="nea-svg-rect-circle" cx="100" cy="200" r="10"></circle></svg></g>
I’m trying to select each object, get all field from the boxes and move,
I having problem with xpath and selecting by class.
Do you have a suggestion?
I'm thinking in getting all classes "nea-svg"", the the text of each. After this, i may get all related "nea-sequence-editor-brick".
As this is a big project, i added a extension go chrome to get xpath and css selectors but, even this fails to retrieve the correct one.
I'm new in protractor and jasmine.
So the goal here is to have a 2 color diagonal hatch pattern that can be rotated to arbitrary angles dynamically (fyi it's being applied to a D3 map w/zooming).
I found the "SVG Pattern Contains Whitespace Between Repetitions in Firefox(1) question, however the solution is not very flexible rotation-wise and I couldn't make it work with the 2 colors bars.
Here's a jsfiddle test case.. The first 4 are my technique rotated differently. The last one is an attempt to adapt follow the previously mentioned answer's advice.
Chrome renders it fine(2) (as does Safari and IE).
But Firefox has these nasty lines where it tiles, but only when the pattern is rotated to something other than 90deg increments.
Any ideas?
Here's the contents of the Jsfiddle:
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd">
<svg xml:space="preserve" width="925" height="810" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="hatch" width="10" height="10" patternUnits="userSpaceOnUse">
<line x1="0" y1="0" x2="0" y2="10" style="stroke:black; stroke-width:16" />
<line x1="13" y1="0" x2="13" y2="10" style="stroke:gray; stroke-width:16" />
</pattern>
<pattern id="hatch45" width="10" height="10" patternTransform="rotate(5 0 0)" patternUnits="userSpaceOnUse">
<line x1="-2" y1="-2" x2="-2" y2="12" style="stroke:black; stroke-width:16" overflow="visible" />
<line x1="12" y1="-2" x2="12" y2="12" style="stroke:gray; stroke-width:16" overflow="visible" />
</pattern>
<pattern id="hatch80" width="10" height="10" patternTransform="rotate(80 0 0)" patternUnits="userSpaceOnUse">
<line x1="0" y1="0" x2="0" y2="10" style="stroke:black; stroke-width:16" />
<line x1="13" y1="0" x2="13" y2="10" style="stroke:gray; stroke-width:16" />
</pattern>
<pattern id="hatch90" width="10" height="10" patternTransform="rotate(90 0 0)" patternUnits="userSpaceOnUse">
<line x1="0" y1="0" x2="0" y2="10" style="stroke:black; stroke-width:16" />
<line x1="13" y1="0" x2="13" y2="10" style="stroke:gray; stroke-width:16" />
</pattern>
<pattern x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" id="line-fill" viewBox="0 0 20 20" overflow="visible" patternTransform="rotate(80 0 0)">
<g stroke-width="20">
<line x1="0" y1="-10" x2="0" y2="30" stroke="black" />
<line x1="20" y1="-10" x2="20" y2="30" stroke="gray" />
</g>
</pattern>
</defs>
<g>
<rect style="fill:url(#hatch45);" x="10" y="0" width="200" height="130" />
<rect style="fill:url(#hatch80);" x="10" y="150" width="200" height="130" />
<rect style="fill:url(#hatch90);" x="10" y="300" width="200" height="130" />
<rect style="fill:url(#hatch);" x="10" y="450" width="200" height="130" />
<rect style="fill:url(#line-fill);" x="10" y="600" width="200" height="130" />
</g>
</svg>
1: stackoverflow.com/questions/19391071/svg-pattern-contains-whitespace-between-repetitions-in-firefox
2: imgur.com/c8SxdGG
I would like to read the width of <text> elements, created in d3, after they're created.
I have tried
svg.selectAll("text")
.each(function () {
console.log('text', d3.select(this).style("width"));
}); // 'auto'
and
svg.selectAll("text")
.each(function () {
console.log('text', $(this).css("width"));
}); // '0px'
Thanks in advance
In a selection method (such as attr) :
this.getComputedTextLength().
In a selection of one element, you can say
selection.node().getComputedTextLength().
You can also use getBBox for the width and height
You may use:
var wh = {w:-1,h:-1};
Array.from(document.querySelectorAll('text')).map(function(ele) {
var bbox = ele.getBoundingClientRect();
wh = {
w: (wh.w<bbox.width) ? bbox.width :wh.w,
h: (wh.h<bbox.height) ? bbox.height :wh.h
}
})
After this wh.w will contain largest width and wh.h will contain largest height of any text. You should then enter a more precise CSS selector to match your needs.
Example based on Rachel Gallen using getComputedTextLength() function created in 2020 and that works on Chrome.
<svg xmlns="http://www.w3.org/2000/svg" version="2.0" width="800px" height="600px">
<script type="text/javascript" href="https://d3js.org/d3.v5.min.js"></script>
<script type="text/JavaScript">
// select Tooltip <text> element by 'id' using d3 library
var tooltip = d3.select("#tooltip-text");
// change Tooltip text
var sTooltip = "tooltip string with more information";
tooltip.node().innerHTML = sTooltip;
// compute text length
var iTextLength = tooltip.node().getComputedTextLength();
</script>
<rect id='tooltip-rect' x='20' y='20' width='100' height='25' fill="yellow"/>
<text id='tooltip-text' x='0' y='0'>
Tooltip: ?
</text>
</svg>
Using this technic, I have now tooltip when dragging mouse over some device.
document.addEventListener("DOMContentLoaded", function(event) {
var tooltip = d3.select("#tooltip-text");
var toolrec = d3.select("#tooltip-rect");
var iTextLength = 0;
d3.select("svg").selectAll("use")
.on("mouseover", function ()
{
var sTooltip = "";
var e = this.nextElementSibling;
if (e != null)
{
if (e.className.baseVal == "info")
{
sTooltip = e.innerHTML;
}
}
if (sTooltip == "")
{
sTooltip = this.href.baseVal;
}
if (sTooltip == "")
{
sTooltip = "? Tooltip";
}
tooltip.node().innerHTML = sTooltip;
iTextLength = tooltip.node().getComputedTextLength();
tooltip.style("opacity", "1");
toolrec.style("opacity", "1");
})
.on("mousemove", function ()
{
toolrec.attr("x", d3.select(this).attr("x") - 5);
toolrec.attr("y", d3.select(this).attr("y") - 12);
toolrec.attr("width", iTextLength + 10);
tooltip.attr("x", d3.select(this).attr("x"));
tooltip.attr("y", d3.select(this).attr("y"));
})
.on("mouseout", function ()
{
tooltip.style("opacity", "0");
toolrec.style("opacity", "0");
return true;
});
});
:root {
--line-color: black;
--line-width: 2;
}
line, polyline, rect, circle, path {
stroke-width: var(--line-width);
stroke: var(--line-color);
}
#tooltip-text {
max-width: 800px;
text-align:left;
transition: opacity 0.4s;
pointer-events:none;
opacity: 0;
padding: 4px;
font-family: Arial;
font-size: 14;
}
#tooltip-rect {
background: yellow;
border:solid gray;
max-width: 800px;
transition: opacity 0.4s;
pointer-events:none;
opacity: 0;
}
svg {
margin:10px 20px;
overflow:visible;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.5.0/d3.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" version="2.0" width="8000px" height="6000px">
<defs>
<g id="differentiel">
<rect x="-5" y="0" width="40" height="40" style="opacity:0" />
<g transform="rotate(-20,0,0)">
<polyline points="0 0 0 40 5 40 5 35 0 35" fill="none" />
</g>
</g>
<g id="disjoncteur" transform="rotate(-20,0,0)">
<polyline points="0 0 0 40 5 40 5 35 0 35" fill="none" />
</g>
<g id="prise">
<path d="m40,-20 a20,20 0 0,0 0,40 z" fill="white" style="stroke:white" />
<line x1="0" y1="0" x2="20" y2="0" />
<line x1="20" y1="-15" x2="20" y2="15" />
<path d="m40,-20 a20,20 0 0,0 0,40" fill="none" />
<line x1="40" y1="-20" x2="40" y2="-28" />
<line x1="40" y1="20" x2="40" y2="28" />
</g>
<g id="connexion">
<rect x="0" y="-10" width="20" height="20" fill="white" />
</g>
<g id="lampe">
<circle cx="0" cy="0" r="15" stroke="none" style="opacity:0" />
<line x1="-10" y1="-10" x2="10" y2="10" />
<line x1="10" y1="-10" x2="-10" y2="10" />
</g>
<g id="interrupteur">
<circle cx="10" cy="0" r="10" fill="white" />
<g transform="rotate(-60 10 0)">
<line x1="20" y1="0" x2="50" y2="0" />
</g>
</g>
<g id="int-sans-fil">
<rect x="0" y="-5" width="10" height="10" fill="white" />
</g>
<g id="int-wifi">
<rect x="0" y="-5" width="10" height="10" fill="white" />
</g>
<g id="int-radio">
<rect x="0" y="-5" width="10" height="10" fill="white" />
</g>
<g id="int-unipolaire">
<circle cx="10" cy="0" r="10" fill="white" />
<g transform="rotate(-60 10 0)">
<line x1="20" y1="0" x2="50" y2="0" />
<line x1="50" y1="0" x2="50" y2="5" />
</g>
</g>
<g id="int-bipolaire">
<circle cx="10" cy="0" r="10" fill="white" />
<g transform="rotate(-60 10 0)">
<line x1="20" y1="0" x2="50" y2="0" />
<line x1="50" y1="0" x2="50" y2="5" />
<line x1="45" y1="0" x2="45" y2="5" />
</g>
</g>
<g id="int-va-et-vient">
<circle cx="10" cy="0" r="10" fill="white" />
<g transform="rotate(-60 10 0)">
<line x1="20" y1="0" x2="50" y2="0" />
<line x1="50" y1="0" x2="50" y2="5" />
<line x1="0" y1="0" x2="-30" y2="0" />
<line x1="-30" y1="0" x2="-30" y2="-5" />
</g>
</g>
<g id="inverseur">
<g transform="translate(w²²0 0)">
<circle cx="10" cy="0" r="10" fill="white" />
<g transform="rotate(-60 10 0)">
<line x1="20" y1="0" x2="50" y2="0" />
<line x1="50" y1="0" x2="50" y2="5" />
<line x1="0" y1="0" x2="-30" y2="0" />
<line x1="-30" y1="0" x2="-30" y2="-5" />
</g>
<g transform="rotate(60 10 0)">
<line x1="20" y1="0" x2="50" y2="0" />
<line x1="50" y1="0" x2="50" y2="-5" />
<line x1="0" y1="0" x2="-30" y2="0" />
<line x1="-30" y1="0" x2="-30" y2="5" />
</g>
</g>
</g>
<g id="machine-à-laver">
<rect x="0" y="-20" width="40" height="40" fill="white" fill-opacity="0.0" />
<circle cx="20" cy="0" r="12" stroke="blue" fill="none" />
<circle cx="20" cy="0" r="5" stroke="blue" fill="red" />
</g>
<g id="séchoir">
<rect x="0" y="-20" width="40" height="40" fill="white" fill-opacity="0.0" />
<circle cx="15" cy="-8" r="5" fill="none" />
<circle cx="25" cy="-8" r="5" fill="none" />
<circle cx="20" cy="8" r="5" fill="black" />
</g>
<g id="chauffe-eau">
<circle cx="20" cy="0" r="20" fill="white" fill-opacity="0.0" />
<circle cx="20" cy="0" r="15" fill="cyan" />
<path d="m5,0 l 5,-5 l 10,10 l 10,-10 l 5,5" fill="none" />
</g>
<g id="chauffe-eau-direct">
<circle cx="20" cy="0" r="20" fill="cyan" />
<path d="m0,0 l 5,-5 l 10,10 l 10,-10 l 10,10 l 5,-5" fill="none" />
</g>
<g id="télérupteur">
<rect x="0" y="-10" width="40" height="20" fill="white" />
<path d="m5,5 h10 v-10 m20,10 h-10 v-10" fill="none" />
</g>
<g id="télérupteur-radio">
<rect x="0" y="-10" width="40" height="20" fill="none" />
<path d="m5,5 h10 v-10 m20,10 h-10 v-10" fill="none" />
<path d="M25,15 A5,5 0 0,1 15,15" fill="none" stroke-width="1" />
<path d="M30,15 A10,10 0 0,1 10,15" fill="none" stroke-width="1" />
<path d="M35,15 A15,15 0 0,1 5,15" fill="none" stroke-width="1" />
</g>
<g id="télérupteur-wifi">
<rect x="0" y="-10" width="40" height="20" fill="none" />
<path d="m5,5 h10 v-10 m20,10 h-10 v-10" fill="none" />
</g>
<g id="bouton-poussoir">
<circle cx="10" cy="0" r="10" fill="none" />
<circle cx="10" cy="0" r="5" fill="red" />
</g>
<g id="transformateur">
<circle cx="10" cy="0" r="10" fill="none" />
<circle cx="20" cy="0" r="10" fill="none" />
</g>
<g id="lave-vaisselle">
<rect x="0" y="-20" width="40" height="40" fill="white" />
<line x1="0" y1="-20" x2="40" y2="20" />
<line x1="0" y1="20" x2="40" y2="-20" />
<circle cx="20" cy="0" r="10" fill="white" />
</g>
<g id="plaque-cuisson">
<rect x="0" y="-20" width="40" height="40" fill="white" />
<circle cx="30" cy="-10" r="5" stroke="blue" fill="none" />
<circle cx="30" cy="10" r="5" stroke="blue" fill="none" />
<circle cx="10" cy="10" r="5" stroke="blue" fill="none" />
</g>
<g id="télévision">
<rect x="0" y="-20" width="60" height="40" fill="white" />
<rect x="5" y="-15" width="50" height="30" fill="none" />
<line x1="30" y1="20" x2="30" y2="25" />
<line x1="20" y1="25" x2="40" y2="25" />
</g>
<g id="ordinateur">
<rect x="0" y="-20" width="40" height="30" fill="white" />
<rect x="5" y="-15" width="30" height="20" fill="none" />
<rect x="0" y="15" width="40" height="10" fill="none" />
<line x1="20" y1="20" x2="35" y2="20" />
</g>
<g id="four-classique">
<rect x="0" y="-20" width="40" height="40" fill="white" />
<line x1="0" y1="-10" x2="40" y2="-10" />
<circle cx="20" cy="5" r="5" fill="none" />
</g>
<g id="four-pyrolyse">
<rect x="0" y="-20" width="40" height="40" fill="white" />
</g>
<g id="micro-onde">
<rect x="0" y="-20" width="40" height="40" fill="white" fill-opacity="0.0" />
<g transform="scale(0.2 0.2)">
<path d="M20 -30 C 40 -80 , 80 -80 , 100 -30 S 160 30, 180 -30" stroke="black" fill="none" />
<path d="M20 0 C 40 -50 , 80 -50 , 100 0 S 160 50, 180 0" stroke="black" fill="none" />
<path d="M20 30 C 40 -20 , 80 -20 , 100 30 S 160 80, 180 30" stroke="black" fill="none" />
</g>
</g>
<g id="frigo">
<rect x="0" y="-20" width="40" height="40" fill="white" />
<text x="20" y="6" dominant-baseline="middle" text-anchor="middle" font-size="24">*</text>
</g>
<g id="congélateur">
<rect x="0" y="-20" width="40" height="40" fill="white" />
<text x="20" y="4" dominant-baseline="middle" text-anchor="middle">***</text>
</g>
<g id="radiateur">
<rect x="0" y="-15" width="60" height="30" fill-opacity="0.0" />
<path d="m0,0 l5,0 l 5,-10 l 10,20 l 10,-20 l 10,20 l 10,-20 l 5,10 l5,0" fill="none" stroke="black" stroke-width="1" />
</g>
<g id="volet">
<rect x="0" y="-20" width="40" height="40" fill-opacity="0.0" />
<path d="M0,-15 h 40 M0,-10 h 40 M0,-5 h 40 M0,0 h 40 M0,5 h40" fill="none" stroke="black" stroke-width="1" />
</g>
<g id="spot">
<path d="m10,-10 a10,10 0 0,0 0,20" fill="none" />
<circle cx="10" cy="0" r="5" fill="yellow" />
<g transform="rotate(-45,10,0)">
<line x1="5" y1="0" x2="15" y2="0" stroke-width="1" />
<line x1="10" y1="-5" x2="10" y2="5" stroke-width="1" />
</g>
</g>
<g id="neon-simple">
<line x1="0" y1="-5" x2="0" y2="5" stroke="black" />
<line x1="40" y1="-5" x2="40" y2="5" stroke="black" />
<rect x="0" y="-2" width="40" height="4" fill="yellow" stroke="black" stroke-width="1" />
</g>
<g id="neon-double">
<line x1="0" y1="-7" x2="0" y2="7" stroke="black" />
<line x1="40" y1="-7" x2="40" y2="7" stroke="black" />
<rect x="0" y="-6" width="40" height="4" fill="yellow" stroke="black" stroke-width="1" />
<rect x="0" y="2" width="40" height="4" fill="yellow" stroke="black" stroke-width="1" />
</g>
<g id="compteur">
<rect x="0" y="-20" width="40" height="40" fill="none" />
<line x1="0" y1="-10" x2="40" y2="-10" />
<text x="20" y="5" dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="16">kWh</text>
</g>
</defs>
<line x1='100' y1='50' x2='100' y2='90'/>
<text x ='110' y='70' fill='black' font-family='Arial' font-size='20'>Différenciel PRINCIPAL</text>
<text x ='110' y='100' fill='black' font-family='Arial' font-size='12'>Δ300 mA</text>
<use href='#differentiel' x='100' y='90'/>
<line x1='100' y1='130' x2='100' y2='170'/>
<line x1='100' y1='170' x2='100' y2='210'/>
<text x ='110' y='190' fill='black' font-family='Arial' font-size='20'>B</text>
<text x ='110' y='220' fill='black' font-family='Arial' font-size='12'>10A</text>
<use href='#differentiel' x='100' y='210'/>
<desc class='info'>
B: éclairage Etage + Cave + Hall + WC + cagibi +
</desc>
<line x1='100' y1='250' x2='100' y2='330'/>
<text x='90' y='334' fill='black' font-family='Arial' font-size='16' text-anchor='end'>B1</text>
<line x1='100' y1='330' x2='120' y2='330'/>
<use href='#int-va-et-vient' x='120' y='330'/>
<desc class='info'>
hall: interrupteur à droite des escaliers
</desc>
<use href='#int-va-et-vient' x='140' y='330'/>
<desc class='info'>
hall: interrupteur à gauche de la porte de la cuisine
</desc>
<line x1='160' y1='330' x2='200' y2='330'/>
<use href='#lampe' x='200' y='330'/>
<desc class='info'>
lampe Hall dans l'entrée
</desc>
<line x1='100' y1='330' x2='100' y2='410'/>
<text x='90' y='414' fill='black' font-family='Arial' font-size='16' text-anchor='end'>B7</text>
<line x1='100' y1='410' x2='120' y2='410'/>
<use href='#int-unipolaire' x='120' y='410'/>
<desc class='info'>
chambre Est: interrupteur à gauche de la porte
</desc>
<line x1='140' y1='410' x2='180' y2='410'/>
<use href='#lampe' x='180' y='410'/>
<desc class='info'>
lampe chambre Est (Musson)
</desc>
<line x1='100' y1='410' x2='100' y2='490'/>
<text x='90' y='494' fill='black' font-family='Arial' font-size='16' text-anchor='end'>B8</text>
<line x1='100' y1='490' x2='120' y2='490'/>
<use href='#int-va-et-vient' x='120' y='490'/>
<desc class='info'>
interrupteur à gauche de l'escalier
</desc>
<line x1='140' y1='490' x2='170' y2='490'/>
<use href='#inverseur' x='170' y='490'/>
<desc class='info'>
interrupteur à droite du passage entre caves
</desc>
<line x1='190' y1='490' x2='220' y2='490'/>
<use href='#int-va-et-vient' x='220' y='490'/>
<desc class='info'>
interrupteur à droite de la porte de garage
</desc>
<line x1='240' y1='490' x2='280' y2='490'/>
<use href='#lampe' x='280' y='490'/>
<desc class='info'>
lampes cave petit garage
</desc>
<line x1='100' y1='490' x2='100' y2='570'/>
<text x ='90' y='574' fill='black' font-family='Arial' font-size='16' text-anchor='end'>B12</text>
<line x1='100' y1='570' x2='120' y2='570'/>
<use href='#télérupteur-radio' x='120' y='570'/>
<use href='#int-radio' x='140' y='610'/>
<use href='#int-radio' x='160' y='610'/>
<use href='#int-radio' x='180' y='610'/>
<line x1='160' y1='570' x2='200' y2='570'/>
<use href='#lampe' x='200' y='570'/>
<desc class='info'>
lampe couloir étage Ouest (Signeulx)
</desc>
<line x1='100' y1='170' x2='350' y2='170'/>
<line x1='350' y1='170' x2='350' y2='210'/>
<text x ='360' y='190' fill='black' font-family='Arial' font-size='20'>C</text>
<text x ='360' y='220' fill='black' font-family='Arial' font-size='12'>25A</text>
<use href='#differentiel' x='350' y='210'/>
<desc class='info'>
C: triphasé cuisine
</desc>
<line x1='350' y1='250' x2='350' y2='330'/>
<text x ='340' y='334' fill='black' font-family='Arial' font-size='16' text-anchor='end'>C1</text>
<line x1='350' y1='330' x2='370' y2='330'/>
<use href='#connexion' x='370' y='330'/>
<desc class='info'>
connection directe
</desc>
<line x1='390' y1='330' x2='410' y2='330'/>
<line x1='410' y1='330' x2='430' y2='330'/>
<use href='#four-classique' x='430' y='330'/>
<desc class='info'>
four Siemens
</desc>
<line x1='350' y1='330' x2='350' y2='410'/>
<text x ='340' y='414' fill='black' font-family='Arial' font-size='16' text-anchor='end'>C2</text>
<line x1='350' y1='410' x2='370' y2='410'/>
<use href='#connexion' x='370' y='410'/>
<desc class='info'>
connection directe
</desc>
<line x1='390' y1='410' x2='410' y2='410'/>
<line x1='410' y1='410' x2='430' y2='410'/>
<use href='#micro-onde' x='430' y='410'/>
<desc class='info'>
micro-onde Siemens
</desc>
<line x1='350' y1='170' x2='530' y2='170'/>
<line x1='530' y1='170' x2='530' y2='210'/>
<text x ='540' y='190' fill='black' font-family='Arial' font-size='20'>Différentiel SECONDAIRE</text>
<text x ='540' y='220' fill='black' font-family='Arial' font-size='12'>Δ30 mA</text>
<use href='#differentiel' x='530' y='210'/>
<line x1='530' y1='250' x2='530' y2='290'/>
<line x1='530' y1='290' x2='530' y2='330'/>
<text x ='540' y='310' fill='black' font-family='Arial' font-size='20'>E</text>
<text x ='540' y='340' fill='black' font-family='Arial' font-size='12'>16A</text>
<use href='#differentiel' x='530' y='330'/>
<desc class='info'>
E: éclairage et 2 prises dans salle de bain principale
</desc>
<line x1='530' y1='370' x2='530' y2='450'/>
<text x='520' y='454' fill='black' font-family='Arial' font-size='16' text-anchor='end'>E1</text>
<line x1='530' y1='450' x2='550' y2='450'/>
<use href='#int-unipolaire' x='550' y='450'/>
<desc class='info'>
interrupteur à gauche de la colonne de descente d'eau
</desc>
<line x1='570' y1='450' x2='610' y2='450'/>
<use href='#lampe' x='610' y='450'/>
<desc class='info'>
lampe salle de bain
</desc>
<line x1='530' y1='450' x2='530' y2='530'/>
<text x ='520' y='534' fill='black' font-family='Arial' font-size='16' text-anchor='end'>E2</text>
<use href='#prise' x='530' y='530'/>
<desc class='info'>
bloc prises à gauche de la colonne de descente d'eau
</desc>
<use href='#prise' x='550' y='530'/>
<desc class='info'>
bloc prises à gauche de la colonne de descente d'eau
</desc>
<line x1='530' y1='290' x2='680' y2='290'/>
<line x1='680' y1='290' x2='680' y2='330'/>
<text x ='690' y='310' fill='black' font-family='Arial' font-size='20'>F</text>
<text x ='690' y='340' fill='black' font-family='Arial' font-size='12'>16A</text>
<use href='#differentiel' x='680' y='330'/>
<desc class='info'>
F: Salle-de-bain ETAGE + prise TV + prise PC bureau
</desc>
<line x1='680' y1='370' x2='680' y2='450'/>
<text x ='670' y='454' fill='black' font-family='Arial' font-size='16' text-anchor='end'>F1</text>
<use href='#prise' x='680' y='450'/>
<desc class='info'>
prise TV au Salon
</desc>
<line x1='680' y1='450' x2='720' y2='450'/>
<line x1='720' y1='450' x2='740' y2='450'/>
<use href='#télévision' x='740' y='450'/>
<desc class='info'>
TV Philips
</desc>
<line x1='680' y1='450' x2='680' y2='530'/>
<text x ='670' y='534' fill='black' font-family='Arial' font-size='16' text-anchor='end'>F2</text>
<use href='#prise' x='680' y='530'/>
<desc class='info'>
prise PC au Bureau
</desc>
<line x1='680' y1='530' x2='720' y2='530'/>
<line x1='720' y1='530' x2='740' y2='530'/>
<use href='#ordinateur' x='740' y='530'/>
<desc class='info'>
ordinateur Dell
</desc>
<line x1='680' y1='530' x2='680' y2='610'/>
<text x ='670' y='614' fill='black' font-family='Arial' font-size='16' text-anchor='end'>F3</text>
<line x1='680' y1='610' x2='700' y2='610'/>
<use href='#télérupteur-radio' x='700' y='610'/>
<use href='#int-radio' x='720' y='650'/>
<line x1='740' y1='610' x2='780' y2='610'/>
<use href='#lampe' x='780' y='610'/>
<desc class='info'>
Salle-de-bain: lampe plafond
</desc>
<line x1='680' y1='610' x2='680' y2='690'/>
<text x ='670' y='694' fill='black' font-family='Arial' font-size='16' text-anchor='end'>F4</text>
<use href='#prise' x='680' y='690'/>
<desc class='info'>
Salle-de-bain: lampe meuble
</desc>
<line x1='680' y1='690' x2='680' y2='770'/>
<text x ='670' y='774' fill='black' font-family='Arial' font-size='16' text-anchor='end'>F5</text>
<use href='#prise' x='680' y='770'/>
<desc class='info'>
Salle-de-bain: prise radiateur
</desc>
<line x1='680' y1='770' x2='720' y2='770'/>
<line x1='720' y1='770' x2='740' y2='770'/>
<use href='#radiateur' x='740' y='770'/>
<desc class='info'>
radiateur Jaga
</desc>
<line x1='680' y1='770' x2='680' y2='850'/>
<text x ='670' y='854' fill='black' font-family='Arial' font-size='16' text-anchor='end'>F6</text>
<use href='#prise' x='680' y='850'/>
<desc class='info'>
Salle-de-bain: bloc de prises sous le meuble
</desc>
<use href='#prise' x='700' y='850'/>
<desc class='info'>
Salle-de-bain: bloc de prises sous le meuble
</desc>
<line x1='680' y1='290' x2='860' y2='290'/>
<line x1='860' y1='290' x2='860' y2='330'/>
<text x ='870' y='310' fill='black' font-family='Arial' font-size='20'>G</text>
<text x ='870' y='340' fill='black' font-family='Arial' font-size='12'>16A</text>
<use href='#differentiel' x='860' y='330'/>
<desc class='info'>
G: Salle-de-bain PRINCIPALE + Bloc machines à laver
</desc>
<line x1='860' y1='370' x2='860' y2='450'/>
<text x ='850' y='454' fill='black' font-family='Arial' font-size='16' text-anchor='end'>G1</text>
<use href='#prise' x='860' y='450'/>
<desc class='info'>
bloc de prises à l'évier
</desc>
<use href='#prise' x='880' y='450'/>
<desc class='info'>
bloc de prises à l'évier
</desc>
<line x1='860' y1='450' x2='860' y2='530'/>
<text x ='850' y='534' fill='black' font-family='Arial' font-size='16' text-anchor='end'>G2</text>
<use href='#prise' x='860' y='530'/>
<desc class='info'>
lampe meuble
</desc>
<line x1='860' y1='530' x2='860' y2='610'/>
<text x ='850' y='614' fill='black' font-family='Arial' font-size='16' text-anchor='end'>G3</text>
<use href='#prise' x='860' y='610'/>
<desc class='info'>
bloc de prises au petit garage à gauche de l'évier
</desc>
<use href='#prise' x='880' y='610'/>
<desc class='info'>
bloc de prises au petit garage à gauche de l'évier
</desc>
<use href='#prise' x='900' y='610'/>
<desc class='info'>
bloc de prises au petit garage à gauche de l'évier
</desc>
<use href='#prise' x='920' y='610'/>
<desc class='info'>
bloc de prises au petit garage à gauche de l'évier
</desc>
<line x1='920' y1='610' x2='960' y2='610'/>
<line x1='960' y1='610' x2='980' y2='610'/>
<use href='#machine-à-laver' x='980' y='610'/>
<desc class='info'>
machine à laver
</desc>
<line x1='530' y1='170' x2='1080' y2='170'/>
<line x1='1080' y1='170' x2='1080' y2='210'/>
<text x ='1090' y='190' fill='black' font-family='Arial' font-size='20'>I</text>
<text x ='1090' y='220' fill='black' font-family='Arial' font-size='12'>16A</text>
<use href='#differentiel' x='1080' y='210'/>
<desc class='info'>
I: chambre étage Ouest (Signeulx)
</desc>
<line x1='1080' y1='250' x2='1080' y2='330'/>
<text x ='1070' y='334' fill='black' font-family='Arial' font-size='16' text-anchor='end'>I1</text>
<use href='#prise' x='1080' y='330'/>
<desc class='info'>
prise à gauche de la porte
</desc>
<line x1='1080' y1='330' x2='1080' y2='410'/>
<text x ='1070' y='414' fill='black' font-family='Arial' font-size='16' text-anchor='end'>I2</text>
<use href='#prise' x='1080' y='410'/>
<desc class='info'>
prise radiateur en dessous de la fenêtre
</desc>
<line x1='1080' y1='410' x2='1120' y2='410'/>
<line x1='1120' y1='410' x2='1140' y2='410'/>
<use href='#radiateur' x='1140' y='410'/>
<desc class='info'>
radiateur Siemens
</desc>
<line x1='1080' y1='410' x2='1080' y2='490'/>
<text x ='1070' y='494' fill='black' font-family='Arial' font-size='16' text-anchor='end'>I3</text>
<line x1='1080' y1='490' x2='1100' y2='490'/>
<use href='#connexion' x='1100' y='490'/>
<desc class='info'>
volet chambre étage Ouest
</desc>
<line x1='1120' y1='490' x2='1140' y2='490'/>
<line x1='1140' y1='490' x2='1160' y2='490'/>
<use href='#volet' x='1160' y='490'/>
<desc class='info'>
volet
</desc>
<line x1='1080' y1='490' x2='1080' y2='570'/>
<text x ='1070' y='574' fill='black' font-family='Arial' font-size='16' text-anchor='end'>I4</text>
<use href='#prise' x='1080' y='570'/>
<desc class='info'>
bloc de prises à gauche de la paque de cuisson en vitrocéramique
</desc>
<use href='#prise' x='1100' y='570'/>
<desc class='info'>
bloc de prises à gauche de la paque de cuisson en vitrocéramique
</desc>
<use href='#prise' x='1120' y='570'/>
<desc class='info'>
bloc de prises à gauche de la paque de cuisson en vitrocéramique
</desc>
<line x1='1080' y1='170' x2='1260' y2='170'/>
<line x1='1260' y1='170' x2='1260' y2='210'/>
<text x ='1270' y='190' fill='black' font-family='Arial' font-size='20'>J</text>
<text x ='1270' y='220' fill='black' font-family='Arial' font-size='12'>16A</text>
<use href='#differentiel' x='1260' y='210'/>
<desc class='info'>
J: Prises bloc de cuisson
</desc>
<line x1='1260' y1='250' x2='1260' y2='330'/>
<text x ='1250' y='334' fill='black' font-family='Arial' font-size='16' text-anchor='end'>J1</text>
<use href='#prise' x='1260' y='330'/>
<desc class='info'>
bloc de prises à droite de la plaque de cuisson en vitrocéramique
</desc>
<use href='#prise' x='1280' y='330'/>
<desc class='info'>
bloc de prises à droite de la plaque de cuisson en vitrocéramique
</desc>
<use href='#prise' x='1300' y='330'/>
<desc class='info'>
bloc de prises à droite de la plaque de cuisson en vitrocéramique
</desc>
<rect id='tooltip-rect' x='20' y='20' width='100' height='25' fill="yellow"/>
<text id='tooltip-text' x='20' y='20' dominant-baseline="middle" text-anchor="start">
Tooltip: ?
</text>
</svg>