preface
Last week we implemented a basic line chart, so today we will lead you to implement a basic bar chart
Results show
Analysis of the
- The bar chart also has axes and you can use the line chart axis scheme
- A column on which a histogram is drawn.
- Bar diagram animation.
- Bar graph tooltip.
The simple bar chart can be roughly divided into the above four stages.
start
Let me draw my axes
I’ll leave this one out of the way and start drawing using the axis API
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
const data = [50.100.200.300.400.150.250.350];
const xS = d3.scaleBand().domain(['Monday'.'Tuesday'.'Wednesday'.'Thursday'.'Friday'.'Saturday'.'Sunday']).range([0.400]);
const yS = d3.scaleLinear().domain([0.400]).range([400.0]);
function initCanvas() {
// Define the canvas space
d3.select('body')
.append('svg')
.attr('width'.500)
.attr('height'.500)
.attr('class'.'svg')}function drawX() {
const xAxis = d3.axisBottom(xS)
.ticks(7) // Control the number of ticks on the axis
.tickSize(6) // Control the size of the scale
.tickPadding(5) // Set the distance between the label number and the coordinate axis
.tickFormat(d= > d) // Format the label number
d3.select('.svg').append('g')
// Pan to the right position (how to know the right position? You can adjust the DOM manually, or you can structure it in your head, and it's basically just converging.)
.attr('transform'.'translate(50,430)')
.call(xAxis)
}
function drawY() {
const yAxis = d3.axisLeft(yS)
.ticks(7) // Control the number of ticks on the axis
.tickSize(6) // Control the size of the scale
.tickPadding(5) // Set the distance between the label number and the coordinate axis
.tickFormat(d= > d) // Format the label number
d3.select('.svg').append('g')
// Pan to the appropriate position
.attr('transform'.'translate (50, 30)')
.call(yAxis)
}
(async function() {
await initCanvas();
await drawX();
awaitdrawY(); }) ();</script>
Copy the code
Effect presentation:
Conclusion:initCanvas()
Function defines the canvas space,drawX()
Let me draw my X-axis,drawY()
Draw the Y-axis. See the notes for details
A column on which a histogram is drawn
The drawing column is drawn using RECT of SVG, and the position coordinates are placed in the container generated by the coordinate axes in the same way as the line chart in the previous part (DOM below).
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
const data = [50.100.200.300.400.150.250.350];
const xS = d3.scaleBand().domain(['Monday'.'Tuesday'.'Wednesday'.'Thursday'.'Friday'.'Saturday'.'Sunday']).range([0.400]);
const yS = d3.scaleLinear().domain([0.400]).range([400.0]);
function initCanvas() {
// Define the canvas space
d3.select('body')
.append('svg')
.attr('width'.500)
.attr('height'.500)
.attr('class'.'svg')}function drawX() {
const xAxis = d3.axisBottom(xS)
.ticks(7) // Control the number of ticks on the axis
.tickSize(6) // Control the size of the scale
.tickPadding(5) // Set the distance between the label number and the coordinate axis
.tickFormat(d= > {
return d
}) // Format the label number
d3.select('.svg').append('g')
.attr('transform'.'translate(50,430)')
.attr('class'.'x-axis')
.call(xAxis)
}
function drawY() {
const yAxis = d3.axisLeft(yS)
.ticks(7) // Control the number of ticks on the axis
.tickSize(6) // Control the size of the scale
.tickPadding(5) // Set the distance between the label number and the coordinate axis
.tickFormat(d= > {
return d
}) // Format the label number
d3.select('.svg').append('g')
.attr('transform'.'translate (50, 30)')
.attr('class'.'y-axis')
.call(yAxis)
}
function drawRect() {
// The column for drawing the histogram is drawn using the RECT tag of SVG
// The base point in the tick container is the position of the X axis
//1. x = 0;
//2. y = -height;
//3. width = 20;
//4. Height = data[I
d3.selectAll('.x-axis .tick')
.append('rect')
.attr('class'.'rect')
.attr('transform'.`translate(-10, 0)`)
.attr('x'.0)
.attr('width'.20)
.attr('height'.(d, i) = > data[i])
.attr('y'.(d, i) = > -data[i])
.attr('fill'.'#2e6be6')}function drawText() {
// Draw the column text of the bar chart
// The base point in the tick container is the position of the X axis
d3.selectAll('.x-axis .tick')
.append('text')
.attr('class'.'text')
.attr('transform'.`translate(0, 0)`)
.attr('x'.0)
.attr('y'.(d, i) = > -data[i] - 5)
.text((d,i) = > data[i])
.attr('fill'.'#2e6be6');
}
(async function () {
await initCanvas();
await drawX();
await drawY();
await drawText();
awaitdrawRect(); }) ();</script>
Copy the code
Renderings:
Conclusion:drawText()
Function to draw a histogram of the column text, the main attributex
It’s based on a bar chartx
Shaft is so0
.y
It should be column height -5, let higher than column.drawRect
Is the key attribute of the column to draw the bar graph:x
It’s also based on the X-axis so it’s 0,y
Should be the negative of column height, width is given a fixed value20
In order to shift the centertranslate(-10, 0)
Height is the height of the data
Draw the animation effect of the bar chart
I don’t know if you remember the last example in Transition, but the animation of the bar graph is similar to that, the animation of the bar graph is a high transition.
Code examples:
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
const data = [50.100.200.300.400.150.250.350];
const xS = d3.scaleBand().domain(['Monday'.'Tuesday'.'Wednesday'.'Thursday'.'Friday'.'Saturday'.'Sunday']).range([0.400]);
const yS = d3.scaleLinear().domain([0.400]).range([400.0]);
function initCanvas() {
// Define the canvas space
d3.select('body')
.append('svg')
.attr('width'.500)
.attr('height'.500)
.attr('class'.'svg')}function drawX() {
const xAxis = d3.axisBottom(xS)
.ticks(7) // Control the number of ticks on the axis
.tickSize(6) // Control the size of the scale
.tickPadding(5) // Set the distance between the label number and the coordinate axis
.tickFormat(d= > {
return d
}) // Format the label number
d3.select('.svg').append('g')
.attr('transform'.'translate(50,430)')
.attr('class'.'x-axis')
.call(xAxis)
}
function drawY() {
const yAxis = d3.axisLeft(yS)
.ticks(7) // Control the number of ticks on the axis
.tickSize(6) // Control the size of the scale
.tickPadding(5) // Set the distance between the label number and the coordinate axis
.tickFormat(d= > {
return d
}) // Format the label number
d3.select('.svg').append('g')
.attr('transform'.'translate (50, 30)')
.attr('class'.'y-axis')
.call(yAxis)
}
function drawRect() {
// The column for drawing the histogram is drawn using the RECT tag of SVG
// The base point in the tick container is the position of the X axis
//1. x = 0;
//2. y = -height;
//3. width = 20;
//4. Height = data[I
const rect = d3.selectAll('.x-axis .tick')
.append('rect')
.attr('class'.'rect')
.attr('transform'.`translate(-10, 0)`)
.attr('x'.0)
.attr('width'.20)
.attr('height'.0) // Set it to 0 for animation
.attr('y'.0) //height transition y should do the same
.attr('fill'.'#2e6be6')
rect.transition()
.duration(2000) // Add the duration
.delay((d, i) = > 200 * i) // Continuous transition time ** stack **
.ease(d3.easeBounce) // Transition effect
.attr('height'.(d, i) = > data[i])
.attr('y'.(d, i) = > -data[i])
}
function drawText() {
// Draw the column text of the bar chart
// The base point in the tick container is the position of the X axis
const text = d3.selectAll('.x-axis .tick')
.append('text')
.attr('class'.'text')
.attr('transform'.`translate(0, 0)`)
.attr('x'.0)
.attr('y'.0)
.text((d, i) = > data[i])
.attr('fill'.'#2e6be6');
// Text should also be transitioned accordingly
text.transition()
.duration(2000) // Add the duration
.delay((d, i) = > 200 * i) // Continuous transition time ** stack **
.ease(d3.easeBounce) // Transition effect
.attr('y'.(d, i) = > -data[i] - 5)} (async function () {
await initCanvas();
await drawX();
await drawY();
await drawText();
awaitdrawRect(); }) ();</script>
Copy the code
Effect display:
Summary: TransformationdrawText()
Function makes text add transition animation effect, main transitiony
, from0
The transition to-data[i] - 5
Delay causes continuous superposition. transformdrawRect()
The function adds an animated transition effect to the column of a bar graph, mainly a transitionheight
But becausey
withheight
It’s related, so it’s going to transition together.
Add a small tooltip to the bar chart
Add tooltip, mouseover and mouseout are the first to come to mind, add events to D3 with on!!
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
const data = [50.100.200.300.400.150.250.350];
const xS = d3.scaleBand().domain(['Monday'.'Tuesday'.'Wednesday'.'Thursday'.'Friday'.'Saturday'.'Sunday']).range([0.400]);
const yS = d3.scaleLinear().domain([0.400]).range([400.0]);
function initCanvas() {
// Define the canvas space
d3.select('body')
.append('svg')
.attr('width'.500)
.attr('height'.500)
.attr('class'.'svg')}function drawX() {
const xAxis = d3.axisBottom(xS)
.ticks(7) // Control the number of ticks on the axis
.tickSize(6) // Control the size of the scale
.tickPadding(5) // Set the distance between the label number and the coordinate axis
.tickFormat(d= > {
return d
}) // Format the label number
d3.select('.svg').append('g')
.attr('transform'.'translate(50,430)')
.attr('class'.'x-axis')
.call(xAxis)
}
function drawY() {
const yAxis = d3.axisLeft(yS)
.ticks(7) // Control the number of ticks on the axis
.tickSize(6) // Control the size of the scale
.tickPadding(5) // Set the distance between the label number and the coordinate axis
.tickFormat(d= > {
return d
}) // Format the label number
d3.select('.svg').append('g')
.attr('transform'.'translate (50, 30)')
.attr('class'.'y-axis')
.call(yAxis)
}
function drawRect() {
// The column for drawing the histogram is drawn using the RECT tag of SVG
// The base point in the tick container is the position of the X axis
//1. x = 0;
//2. y = -height;
//3. width = 20;
//4. Height = data[I
const rect = d3.selectAll('.x-axis .tick')
.append('rect')
.attr('class'.'rect')
.attr('transform'.`translate(-10, 0)`)
.attr('x'.0)
.attr('width'.20)
.attr('height'.0) // Set it to 0 for animation
.attr('y'.0) //height transition y should do the same
.attr('fill'.'#2e6be6')
.attr('cursor'.'pointer')
rect.transition()
.duration(2000) // Add the duration
.delay((d, i) = > 200 * i) // Continuous transition time ** stack **
.ease(d3.easeBounce) // Transition effect
.attr('height'.(d, i) = > data[i])
.attr('y'.(d, i) = > -data[i])
}
function drawText() {
// Draw the column text of the bar chart
// The base point in the tick container is the position of the X axis
const text = d3.selectAll('.x-axis .tick')
.append('text')
.attr('class'.'text')
.attr('transform'.`translate(0, 0)`)
.attr('x'.0)
.attr('y'.0)
.text((d, i) = > data[i])
.attr('fill'.'#2e6be6');
// Text should also be transitioned accordingly
text.transition()
.duration(2000) // Add the duration
.delay((d, i) = > 200 * i) // Continuous transition time ** stack **
.ease(d3.easeBounce) // Transition effect
.attr('y'.(d, i) = > -data[i] - 5)}// Add events
function addRectEvent() {
d3.selectAll('.x-axis .tick .rect')
.on('mouseover'.(d, i) = > {
// Draw a cross tip, also add to the tick, do not care about the coordinate position.
// The purpose of +2 is that the nth-child starts with the first path in our DOM structure
// Draw the abscissa
d3.selectAll(`.x-axis .tick:nth-child(${i + 2}) `)
.append('line')
.attr('class'.'tip-line')
.attr('x1'.0)
.attr('y1'.0)
.attr('x2'.0)
.attr('y2', -430)
.attr('stroke'.'#3e3e3e');
d3.select(`svg`)
.append('line')
.attr('class'.'tip-line')
.attr('x1'.50)
.attr('y1', d3.event.clientY)
.attr('stroke-dasharray'.'2')
.attr('x2'.440)
.attr('y2', d3.event.clientY)
.attr('stroke'.'#3e3e3e');
d3.select(`svg`)
.append('text')
.attr('width'.'100')
.attr('height'.'50')
.attr('fill'.'red')
.attr('class'.'tip-line')
.attr('x', d3.event.clientX)
.attr('y', d3.event.clientY)
.text((d) = > data[i])
})
.on('mouseout'.() = > {
d3.selectAll('.tip-line').remove(); })} (async function () {
await initCanvas();
await drawX();
await drawY();
await drawText();
await drawRect();
awaitaddRectEvent(); }) ();</script>
Copy the code
Effect drawing display:
Summary: NewaddRectEvent()
Function to add eventson
The keyword.d3.event
Is to get the current event, similar to the event in JS, which contains some information about the current mouse position
conclusion
This time we use d3.transition() to animate our histogram, use the on keyword to add events to our histogram, and use d3.event to retrieve the current mouse position
Would you change tooltip to look like Echarts? I leave it to you 😀
conclusion
- Hi, I am Mihara and thank you for watching and I will work harder.
- Each method is typed out and verified, and can be copied if necessary.
- If you give help a thumbs-up 👍 is even better thank you ~~~~~
- We look forward to your attention