Write in front:
- This article is a simple personal learning summary and class notes arrangement. Most of the knowledge points come from the online live courses of “Kaikaiba” and official materials.
- As it is still in the front-end learning and entry stage, it is inevitable that there will be deviations in the mastery and understanding of knowledge. Therefore, this article is only a personal record, and please do not use it as a basis for information.
To do a good job, he must sharpen his tools. Before we look at D3’s core manipulation of SVG, we first need to know what SVG is and the basic usage of SVG drawing.
SVG Scalable Vector Graphics is a graphics format for describing two-dimensional vector graphics based on extensible Markup Language (EXTENSIBLE Markup Language). SVG, developed by the W3C, is an open standard.
Draw graphics in SVG
SVG root view
The SVG root view can be thought of as a canvas, and all the drawing is done in SVG. Some parameters need to be configured when SVG is initialized:
version
: SVG versionxmlns
: namespacewidth
和height
: SVG canvas for a mealviewBox
: View box, always fully displayed on the canvas, where the graphics are proportionally displayed based on the width and height of the view box
<svg version="1.2"
xmlns="http://www.w3.org/2000/svg"
width="400"
height="400"
viewBox="0 0 400 400"
></svg>
Copy the code
Once the SVG and container are declared, we can draw inside the SVG tag. The common graphics are as follows:
- rectangular
- circular
- Path ==> universal drawing mode
- A straight line
- The circular arc
- Quadratic Bessel curve
- Continuation of quadratic Bessel curves
- Cubic Bezier curves
Let’s look at how to draw the above shapes one by one.
rectangular
<! - the rect rectangular rectangular width on the upper left corner point position x | y | height size -- -- >
<rect x="100" y="100" width="400" height="400" fill="#00acec" />
Copy the code
circular
<! Cx | - circle round cy center position radius r - >
<circle cx="300" cy="300" r="100" fill="#00acec" />
Copy the code
Path-line
There are several common attributes for paths (that is, lines) that control the style of paths:
fill
Used to control the fill color inside the path (closed curve only works)stroks
Used to control the color of the path linestroke-width
Used to control the width of the linestroke-dasharray
Used to control the continuity of lines, often used to draw dashed lines
<! - the path of the path d shape, capital letters for the absolute level, lowercase letters for the relative point starting point: M | M the next point: L | L - >
<path
d=" M 300 300 L 500 300 "
fill="none"
stroke="# 000"
stroke-width="10"
stroke-dasharray="30 10"
/>
Copy the code
Path-arc
<! - arc A | A, Such as 300, 300, A 150 M 200 0 0 0 500 x 300 rx ry radius - axis - rotation axis x [0360] large - the arc - whether flag show maximum arc 0 | 1 sweep - where flag arc side 0 | 1 x y end points -- -- >
<path
d=" M 300 300 A 150 200 20 1 0 500 300 "
fill="none"
stroke="# 000"
stroke-width="5"
/>
Copy the code
Path-quadratic Bezier curves
<! - Q | Q quadratic bezier curve, such as M 200 100 300 400 200 100 100 400 Q are cpx1 cpy1 control points, used to control the degree of curvature of curve 300 of 400 x y are end points -- -- >
<path
d=" M 100 400 Q 200 100 300 400 "
fill="none"
stroke="# 000"
stroke-width="10"
/>
Copy the code
Continuation of quadratic Bessel curves
The us through Q | Q generates a quadratic bezier curve, if we want then, you need to pass T | T declare next curve of all control points.
<! - the continuation of quadratic bezier T | T, such as T 500 400 x y end point x y end point... -->
<path
d=" M 100 400 Q 200 100 300 400 T 500 400 700 400 900 400 "
fill="none"
stroke="# 000"
stroke-width="10"
/>
Copy the code
Cubic Bezier curves
Bessel curve and three times the conic except statement parameters into C | C, the only difference is that the control points from one into two
<! - three times bezier curve C | C, For example, M 100 400 C 200 400 200 200 300 200 the above C 200 400 is CPx1 CPy1 control point 1 followed by THE 200 after C 200 400 200 is cpX2 CPy2 control point 2 and the last 300 200 is the end point of x y -->
<path
d=" M 100 400 C 200 400 200 200 300 200 "
fill="none"
stroke="# 000"
stroke-width="10"
/>
Copy the code
Continuation of the cubic Bezier curve
Same as above, only need to continue through the S | S declare all control points, then through S | S statement of the control points you just need to declare control point 2:
<! - three times the continuation of Bessel curve S | S, such as S 400 400 500 400 400 400 S is cpx2 cpy2 control point is 2 500 400 x y end point -- -- >
<path
d=" M 100 400 C 200 400 200 200 300 200 S 400 400 500 400 600 200 700 200 "
fill="none"
stroke="# 000"
stroke-width="10"
/>
Copy the code
Graphics containers
The path attributes above all use some of the same attributes, such as fill stroke, etc. It is not elegant to write these repeated attributes in each path tag. Also, if the project is large and there are so many similar path tags, we don’t know which path tag corresponds to which function, it’s not easy for us to manage.
Therefore, D3 provides a graphics container G for unified management of graphics that deal with the same object or task and manage common attributes.
<g fill="none" stroke="# 000">
<path
d=" M 100 400 L 200 400 200 200 300 200 400 400 500 400 "
stroke-width="2"
stroke-dasharray="3"
/>
<path
d=" M 100 400 C 200 400 200 200 300 200 S 400 400 500 400 600 200 700 200 "
stroke-width="10"
/>
</g>
Copy the code
Set the SVG style
The SVG style is already controlled by properties such as Fill Stroke while drawing the graphics above. Now let’s take an example of controlling the color of SVG graphics to see how to set the SVG style in detail.
Color according to the color area can be divided into “fill area” and “stroke area”
fill
Property to control the color of the fill area. The default is black, which is responsible for filling the color inside the graphstroke
Property to control the stroke area, default to None, responsible for stroke and filling the color of the shape outline
<circle cx="300" cy="300" r="200" fill="rgba(255,100,0,0.5)"/>
<circle cx="300"
cy="300"
r="200"
fill="none"
stroke="#00acec"/>
Copy the code
All of the above are filled with only solid colors. In fact, there are many different colors that can be used:
- Pure color
- gradient
- Linear gradient
- Radial gradient
- texture
Gradient – Linear gradient
Declare linearGradient parameters using the linearGradient tag. See MDN for the related API.
Declare the parameters of the gradientTransform inside the tag via the gradientTransform attribute:
rotate(a)
Controls the Angle of linear rotationtranslate(x,y)
Control movement in x and y directionsscale(sx,sy)
Controls scaling in x and y directions
Declare the filled node color within the linearGradient with the Stop child tag.
offset
The offset [0, 1]stop-color
color
Finally, inside the graphics TAB, call the gradient fill color with fill=” URL (# ID)”
<defs>
<linearGradient
id="gr"
gradientTransform="rotate(30)"
>
<stop offset="0" stop-color="#fff" />
<stop offset="0.5" stop-color="#00acec" />
<stop offset="1" stop-color="#fff" />
</linearGradient>
</defs>
<circle cx="300" cy="300" r="200" fill="url(#gr)"/>
Copy the code
Gradient – Radial fill
Radial fill is declared via the radialGradient tag, and the rest is exactly the same.
<defs>
<linearGradient
id="gr"
gradientTransform="rotate(30)"
>
<stop offset="0" stop-color="#fff" />
<stop offset="0.5" stop-color="#00acec" />
<stop offset="1" stop-color="#fff" />
</linearGradient>
</defs>
<circle cx="300" cy="300" r="200" fill="url(#gr)" />
Copy the code
Texture shading
The interior of the graphics can be textured by drawing SVG graphics or inserting images.
-
Pattern texture shading
- id
- ViewBox view box
- Width Height Specifies the size of the texture element. 100% is recommended
-
Polygon polygon
- Points: 0,0, 20,50,100 50,80 100,100 80, 100 80,50 100,0 50,20
-
Insert image
- Href image address
- X | y position
- High widht | height width
<polygon points="0,0, 20,50,100 50,80 100,100 80, 100 80,50 100,0 50,20" />
<defs>
<pattern width="30%" height="30%" viewBox="0 0 100 100" id="pt">
<! <polygon points="0,0, 20,50,100 50,80 100,100 80, 100 80,50 100,0 50,20"/>
<image href="./images/rose.jpg" width="100" height="100" />
</pattern>
</defs>
<circle cx="300" cy="300" r="200" fill="url(#pt)" />
Copy the code
Drawing with D3
Now that you have a basic understanding of how SVG draws graphics and how to set styles, let’s use D3 to manipulate DOM elements and SVG to draw a graphic.
Step1 obtain the main container through the D3 select method.
const main=d3.select('#main')
Copy the code
Step2 Establish SVG and container in main container, and set its related attributes
const svg=main.append('svg')
.attr('version'.1.2)
.attr('xmlns'.'http://www.w3.org/2000/svg')
.attr('width'.'100%')
.attr('height'.'100%')
.attr('viewBox'.'- 400-400 800 800)
Copy the code
Step3 create SVG graphics in the SVG container and set related attributes
svg.append('rect')
.attr('x', -200)
.attr('y', -100)
.attr('width'.400)
.attr('height'.200)
.attr('fill'.'red')
Copy the code
We can then add various graphics to the SVG container in the same way, but we will find that this way to write a lot of appen methods, a lot of attR methods, is not elegant. Looking back, the overall call logic is the same whether you create an SVG container in main or add graphics to an SVG container. So we can encapsulate this sequence of call logic into a method.
Step4 encapsulates the Render method, which takes a real DOM node as an argument and returns a real handler. This return function takes the element node and node attribute item to be generated as arguments and returns the actual element node.
function Render(dom) { // The actual DOM node is passed in as an argument and returns a handler directly
return function(shape,option){ // The DOM node you want to generate and the node configuration are passed in as parameters
const obj=dom.append(shape)
for(let [key,val] of Object.entries(option)){
// Iterate over the configured item and assign it to the DOM node object
obj.attr(key,val)
}
return obj
}
}
Copy the code
Thus, we can add DOM nodes directly and elegantly using the Render method:
/* Get the main container */
const main = d3.select("#main");
function Render(dom) {
return function (shape, option) {
const obj = dom.append(shape);
for (let [key, val] of Object.entries(option)) {
obj.attr(key, val);
}
return obj;
};
}
const svg = Render(main)("svg", {
version: 1.2.xmlns: "http://www.w3.org/2000/svg".width: "100%".height: "100%".viewBox: "- 400-400, 800, 800"});// Get the method to create the DOM node
const draw = Render(svg);
/* Draw a graph... * /
draw("rect", {
x: -200.y: 0.width: 400.height: 200.fill: "red"}); draw("rect", {
x: -200.y: 0.width: 400.height: 200.fill: "none".stroke: "# 000"."stroke-width": 40}); draw("rect", {
x: -200.y: 50.width: 400.height: 60.fill: "antiquewhite"}); draw("path", {
d: ` M -100 150 L 100 150 `.fill: "none".stroke: "# 000"."stroke-width": 40}); draw("circle", {
cx: -100.cy: 80.r: 20.fill: "red"}); draw("path", {
d: ` M 80 90 A 20 20 0 0 1 120 90 `.fill: "red"}); draw("path", {
d: ` M -200 -200 C -100 -200 -100 0 0 0 S 100 -200 200 -200 `.fill: "none".stroke: "# 000"."stroke-width": 40});Copy the code
The above is an example of SVG drawing using D3 manipulation of the DOM.