score:1
Accepted answer
Here's a simple way to add a line and a date using your existing scales.
// create a group for your line and date.
const dateLine = chart.append('g')
// position the group: xScale('Jan') is the left edge of the Jan rect, so it needs
// to be in the space between the Dec and Jen rect elements. That space is
// given by xScale.step(), the step size for each month, * the padding / 2
.attr('transform', 'translate(' + (xScale('Jan') - xScale.step() * xScale.padding() * 0.5) + ', 0)')
// append a line, same height as the chart itself
dateLine.append('line')
.attr('y2', height)
// append a text element with the year in it. You can change the x and y attributes
// to position it to your liking
dateLine.append('text')
.text('2018')
.attr('x', 20)
.attr('y', 20)
const sample = [{
month: 'Sep',
value: 78.9,
color: '#000000',
date: '30/09/17'
},
{
month: 'Oct',
value: 75.1,
color: '#00a2ee',
date: '31/10/17'
},
{
month: 'Nov',
value: 68.0,
color: '#fbcb39',
date: '30/11/17'
},
{
month: 'Dec',
value: 67.0,
color: '#007bc8',
date: '31/12/17'
},
{
month: 'Jan',
value: 65.6,
color: '#65cedb',
date: '31/01/18'
},
{
month: 'Feb',
value: 65.1,
color: '#ff6e52',
date: '28/02/18'
},
{
month: 'Mar',
value: 61.9,
color: '#f9de3f',
date: '31/03/18'
},
{
month: 'Apr',
value: 60.4,
color: '#5d2f8e',
date: '30/04/18'
},
{
month: 'May',
value: 59.6,
color: '#008fc9',
date: '31/05/18'
},
{
month: 'Jun',
value: 59.6,
color: '#507dca',
date: '30/06/18'
},
{
month: 'Jul',
value: 80.6,
color: '#507dca',
date: '31/07/18'
},
{
month: 'Aug',
value: 45.6,
color: '#507dca',
date: '31/08/18'
},
{
month: 'Sep ',
value: 78.6,
color: '#507dca',
date: '30/09/18'
}
];
const svg = d3.select('svg');
const svgContainer = d3.select('#container');
const margin = 80;
const width = 1000 - 2 * margin;
const height = 600 - 2 * margin;
const chart = svg.append('g')
.attr('transform', `translate(${margin}, ${margin})`);
const xScale = d3.scaleBand()
.range([0, width])
.domain(sample.map((s) => s.month))
.padding(0.4)
const yScale = d3.scaleLinear()
.range([height, 0])
.domain([0, 100]);
// vertical grid lines
// const makeXLines = () => d3.axisBottom()
// .scale(xScale)
const makeYLines = () => d3.axisLeft()
.scale(yScale)
chart.append('g')
.attr('transform', `translate(0, ${height})`)
.call(d3.axisBottom(xScale));
chart.append('g')
.call(d3.axisLeft(yScale));
const dateLine = chart.append('g')
.attr('transform', 'translate(' +
(xScale('Jan') - xScale.step() * xScale.padding() * 0.5) + ', 0)')
dateLine.append('line')
.attr('y2', height)
dateLine.append('text')
.text('2018')
.attr('x', 20)
.attr('y', 20)
// vertical grid lines
// chart.append('g')
// .attr('class', 'grid')
// .attr('transform', `translate(0, ${height})`)
// .call(makeXLines()
// .tickSize(-height, 0, 0)
// .tickFormat('')
// )
chart.append('g')
.attr('class', 'grid')
.call(makeYLines()
.tickSize(-width, 0, 0)
.tickFormat('')
)
const barGroups = chart.selectAll()
.data(sample)
.enter()
.append('g')
barGroups
.append('rect')
.attr('class', 'bar')
.attr('x', (g) => xScale(g.month))
.attr('y', (g) => yScale(g.value))
.attr('height', (g) => height - yScale(g.value))
.attr('width', xScale.bandwidth())
.on('mouseenter', function(actual, i) {
d3.selectAll('.value')
.attr('opacity', 0)
d3.select(this)
.transition()
.duration(300)
.attr('opacity', 0.6)
.attr('x', (a) => xScale(a.month) - 5)
.attr('width', xScale.bandwidth() + 10)
const y = yScale(actual.value)
line = chart.append('line')
.attr('id', 'limit')
.attr('x1', 0)
.attr('y1', y)
.attr('x2', width)
.attr('y2', y)
barGroups.append('text')
.attr('class', 'divergence')
.attr('x', (a) => xScale(a.month) + xScale.bandwidth() / 2)
.attr('y', (a) => yScale(a.value) + 30)
.attr('fill', 'white')
.attr('text-anchor', 'middle')
.text((a, idx) => {
const divergence = (a.value - actual.value).toFixed(1)
let text = ''
if (divergence > 0) text += '+'
text += `${divergence}%`
return idx !== i ? text : '';
})
})
.on('mouseleave', function() {
d3.selectAll('.value')
.attr('opacity', 1)
d3.select(this)
.transition()
.duration(300)
.attr('opacity', 1)
.attr('x', (a) => xScale(a.month))
.attr('width', xScale.bandwidth())
chart.selectAll('#limit').remove()
chart.selectAll('.divergence').remove()
})
barGroups
.append('text')
.attr('class', 'value')
.attr('x', (a) => xScale(a.month) + xScale.bandwidth() / 2)
.attr('y', (a) => yScale(a.value) + 30)
.attr('text-anchor', 'middle')
.text((a) => `${a.value}%`)
svg
.append('text')
.attr('class', 'label')
.attr('x', -(height / 2) - margin)
.attr('y', margin / 2.4)
.attr('transform', 'rotate(-90)')
.attr('text-anchor', 'middle')
.text('Love meter (%)')
svg.append('text')
.attr('class', 'label')
.attr('x', width / 2 + margin)
.attr('y', height + margin * 1.7)
.attr('text-anchor', 'middle')
.text('Months')
svg.append('text')
.attr('class', 'title')
.attr('x', width / 2 + margin)
.attr('y', 40)
.attr('text-anchor', 'middle')
.text('Most loved programming languages in 2018')
svg.append('text')
.attr('class', 'source')
.attr('x', width - margin / 2)
.attr('y', height + margin * 1.7)
.attr('text-anchor', 'start')
.text('Source: Stack Overflow, 2018')
body {
font-family: 'Open Sans', sans-serif;
}
div#layout {
text-align: center;
}
div#container {
width: 1000px;
height: 600px;
margin: auto;
background-color: #2F4A6D;
}
svg {
width: 100%;
height: 100%;
}
.bar {
fill: #80cbc4;
}
text {
font-size: 12px;
fill: #fff;
}
path {
stroke: gray;
}
line {
stroke: gray;
}
line#limit {
stroke: #FED966;
stroke-width: 3;
stroke-dasharray: 3 6;
}
.grid path {
stroke-width: 0;
}
.grid .tick line {
stroke: #9FAAAE;
stroke-opacity: 0.3;
}
text.divergence {
font-size: 14px;
fill: #2F4A6D;
}
text.value {
font-size: 14px;
}
text.title {
font-size: 22px;
font-weight: 600;
}
text.label {
font-size: 14px;
font-weight: 400;
}
text.source {
font-size: 10px;
}
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id='layout'>
<!-- <h2>Bar chart example</h2> -->
<div id='container'>
<svg />
</div>
</div>
Source: stackoverflow.com
Related Query
- How to add a separator in D3 bar chart D3V3
- How to add a separator in D3 bar chart
- d3.js How to add lines to a bar chart
- How to add a line on x-axis on a horizontal bar chart in d3
- How to add space between bars in a grouped bar chart in a nvd3 grouped multibar chart?
- D3 : How to add labels top of in each bar in grouped bar chart
- How to add text legends in bars of a bar chart in D3?
- How to add live data to stacked bar chart
- how to add tooltip bar chart d3.js
- How to add a tooltip that shows a bar chart onto a d3.js map
- How to add multiple tool tips to a bar chart
- D3 How to add rounded top border to a stacked bar chart
- How to Add Multiline Text Tooltips in Bar Chart D3 JS
- How to add a line at top of stacked bar chart with d3.js?
- D3.js - How to add the general update pattern to a stacked bar chart
- How to add marking in bar chart using d3
- How to add updating labels in D3 Vertical Bar Chart in an Ember Application
- how to add values in one single bar in d3 bar chart
- How can I add columns as categories in a bar chart using Dimple.js?
- How to add a drop shadow to dc.js bar chart rects
- How to add a properly scaled y axis to a stacked d3 bar chart
- How to add tool-tips in d3 js vertically grouped bar chart
- How do i add a fixed text beside bar chart using D3
- How to add Legend bar to Row Chart Dc.js
- How to add x axis text in Bar Chart column
- How to add drop shadow to d3.js pie or donut chart
- How to apply horizontal break to a d3.js bar chart
- How to update d3.js bar chart with new data
- How to add a nice legend to a d3 pie chart
- How to add columnn titles in a Sankey chart networkD3
More Query from same tag
- D3.js Legend Labels
- D3 bar chart uncaught TypeError
- How to correctly add labels to the d3 pie chart?
- Fill rect with pattern
- Alternatives for using forEeach() loop while converting data for D3.js
- Adding text to a rectangle
- Cx of circle is not updated after drag event?
- d3 ignore SVG on selectAll
- how to update reusable nested donut chart?
- embedding an image via d3 does not work
- Populating a Javascript array using MYSQL and JSP
- D3 zoomable sunburst not fully circle
- Access different levels of nested lists in d3
- Material UI Icon and D3
- Updating D3 histogram as data comes in
- Minimise/Limit animation functionality in d3 library
- How can I append an element after select in d3?
- How to select a specific d3 node group element
- Issue in positioning the D3 chart in the specified location wrapped in angular2
- D3 and AngularJS directives
- Error from d3 library?
- D3.js Force links to node border
- how do I set up a grouping query on the server side. I want set up the query so I can use it for a pie chart in front end, using d3js
- Highlight all connected paths from start to end of a sankey diagram using networkD3
- d3: skipping lines when reading in csv file
- Replacing text instead of appending in d3 & Jquery
- D3.js animate rotation
- Why do white spaces get removed from label name?
- Append new shapes to existing shapes within SVG document D3
- How to rotate a group of text elements