I am a data scientist. Mostly use python and SQL for code. I am using data studio for visualizations.So I am unfamiliar to JS. I know-how data studio community visualizations works. I want to make this chart(without markers). I follow this. I tried but didn't get success. Can anybody with me on this? or refer me d3.js data studio integration resources.
I really not sure what you want but for the chart without markers here what I think you want:
function addAxesAndLegend(svg, xAxis, yAxis, margin, chartWidth, chartHeight) {
var legendWidth = 200,
legendHeight = 100;
// clipping to make sure nothing appears behind legend
svg
.append("clipPath")
.attr("id", "axes-clip")
.append("polygon")
.attr(
"points",
-margin.left +
"," +
-margin.top +
" " +
(chartWidth - legendWidth - 1) +
"," +
-margin.top +
" " +
(chartWidth - legendWidth - 1) +
"," +
legendHeight +
" " +
(chartWidth + margin.right) +
"," +
legendHeight +
" " +
(chartWidth + margin.right) +
"," +
(chartHeight + margin.bottom) +
" " +
-margin.left +
"," +
(chartHeight + margin.bottom)
);
var axes = svg.append("g").attr("clip-path", "url(#axes-clip)");
axes
.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + chartHeight + ")")
.call(xAxis);
axes
.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Time (s)");
var legend = svg
.append("g")
.attr("class", "legend")
.attr("transform", "translate(" + (chartWidth - legendWidth) + ", 0)");
legend
.append("rect")
.attr("class", "legend-bg")
.attr("width", legendWidth)
.attr("height", legendHeight);
legend
.append("rect")
.attr("class", "outer")
.attr("width", 75)
.attr("height", 20)
.attr("x", 10)
.attr("y", 10);
legend
.append("text")
.attr("x", 115)
.attr("y", 25)
.text("5% - 95%");
legend
.append("rect")
.attr("class", "inner")
.attr("width", 75)
.attr("height", 20)
.attr("x", 10)
.attr("y", 40);
legend
.append("text")
.attr("x", 115)
.attr("y", 55)
.text("25% - 75%");
legend
.append("path")
.attr("class", "median-line")
.attr("d", "M10,80L85,80");
legend
.append("text")
.attr("x", 115)
.attr("y", 85)
.text("Median");
}
function drawPaths(svg, data, x, y) {
var upperOuterArea = d3.svg
.area()
.interpolate("basis")
.x(function(d) {
return x(d.date) || 1;
})
.y0(function(d) {
return y(d.pct95);
})
.y1(function(d) {
return y(d.pct75);
});
var upperInnerArea = d3.svg
.area()
.interpolate("basis")
.x(function(d) {
return x(d.date) || 1;
})
.y0(function(d) {
return y(d.pct75);
})
.y1(function(d) {
return y(d.pct50);
});
var medianLine = d3.svg
.line()
.interpolate("basis")
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.pct50);
});
var lowerInnerArea = d3.svg
.area()
.interpolate("basis")
.x(function(d) {
return x(d.date) || 1;
})
.y0(function(d) {
return y(d.pct50);
})
.y1(function(d) {
return y(d.pct25);
});
var lowerOuterArea = d3.svg
.area()
.interpolate("basis")
.x(function(d) {
return x(d.date) || 1;
})
.y0(function(d) {
return y(d.pct25);
})
.y1(function(d) {
return y(d.pct05);
});
svg.datum(data);
svg
.append("path")
.attr("class", "area upper outer")
.attr("d", upperOuterArea)
.attr("clip-path", "url(#rect-clip)");
svg
.append("path")
.attr("class", "area lower outer")
.attr("d", lowerOuterArea)
.attr("clip-path", "url(#rect-clip)");
svg
.append("path")
.attr("class", "area upper inner")
.attr("d", upperInnerArea)
.attr("clip-path", "url(#rect-clip)");
svg
.append("path")
.attr("class", "area lower inner")
.attr("d", lowerInnerArea)
.attr("clip-path", "url(#rect-clip)");
svg
.append("path")
.attr("class", "median-line")
.attr("d", medianLine)
.attr("clip-path", "url(#rect-clip)");
}
function startTransitions(svg, chartWidth, chartHeight, rectClip, x) {
rectClip
.transition()
.duration(4000)
.attr("width", chartWidth);
}
function makeChart(data) {
var svgWidth = 960,
svgHeight = 500,
margin = { top: 20, right: 20, bottom: 40, left: 40 },
chartWidth = svgWidth - margin.left - margin.right,
chartHeight = svgHeight - margin.top - margin.bottom;
var x = d3.time
.scale()
.range([0, chartWidth])
.domain(
d3.extent(data, function(d) {
return d.date;
})
),
y = d3.scale
.linear()
.range([chartHeight, 0])
.domain([
0,
d3.max(data, function(d) {
return d.pct95;
})
]);
var xAxis = d3.svg
.axis()
.scale(x)
.orient("bottom")
.innerTickSize(-chartHeight)
.outerTickSize(0)
.tickPadding(10),
yAxis = d3.svg
.axis()
.scale(y)
.orient("left")
.innerTickSize(-chartWidth)
.outerTickSize(0)
.tickPadding(10);
var svg = d3
.select("body")
.append("svg")
.attr("width", svgWidth)
.attr("height", svgHeight)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// clipping to start chart hidden and slide it in later
var rectClip = svg
.append("clipPath")
.attr("id", "rect-clip")
.append("rect")
.attr("width", 0)
.attr("height", chartHeight);
addAxesAndLegend(svg, xAxis, yAxis, margin, chartWidth, chartHeight);
drawPaths(svg, data, x, y);
startTransitions(svg, chartWidth, chartHeight, rectClip, x);
}
var parseDate = d3.time.format("%Y-%m-%d").parse;
d3.json(
"https://gist.githubusercontent.com/rkirsling/33a9e350516da54a5d4f/raw/100dde6bc011fa2604f2c0fb2c160501e220a201/data.json",
function(error, rawData) {
if (error) {
console.error(error);
return;
}
var data = rawData.map(function(d) {
return {
date: parseDate(d.date),
pct05: d.pct05 / 1000,
pct25: d.pct25 / 1000,
pct50: d.pct50 / 1000,
pct75: d.pct75 / 1000,
pct95: d.pct95 / 1000
};
});
makeChart(data);
}
);
#import url(//fonts.googleapis.com/css?family=Open+Sans:400, 700);
svg {
font: 14px "Open Sans";
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axis text {
fill: #000;
}
.axis .tick line {
stroke: rgba(0, 0, 0, 0.1);
}
.area {
stroke-width: 1;
}
.area.outer,
.legend .outer {
fill: rgba(230, 230, 255, 0.8);
stroke: rgba(216, 216, 255, 0.8);
}
.area.inner,
.legend .inner {
fill: rgba(127, 127, 255, 0.8);
stroke: rgba(96, 96, 255, 0.8);
}
.median-line,
.legend .median-line {
fill: none;
stroke: #000;
stroke-width: 3;
}
.legend .legend-bg {
fill: rgba(0, 0, 0, 0.5);
stroke: rgba(0, 0, 0, 0.5);
}
.marker.client .marker-bg,
.marker.client path {
fill: rgba(255, 127, 0, 0.8);
stroke: rgba(255, 127, 0, 0.8);
stroke-width: 3;
}
.marker.server .marker-bg,
.marker.server path {
fill: rgba(0, 153, 51, 0.8);
stroke: rgba(0, 153, 51, 0.8);
stroke-width: 3;
}
.marker path {
fill: none;
}
.legend text,
.marker text {
fill: #fff;
font-weight: bold;
}
.marker text {
text-anchor: middle;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Trend Chart (Area + Line)</title>
</head>
<body>
</body>
<script src="http://d3js.org/d3.v3.js"></script>
</html>
Related
I am trying to create an interactive line chart with circle tooltip like the following https://bl.ocks.org/alandunning/cfb7dcd7951826b9eacd54f0647f48d3 .
My code is below:
HTML
<head>
<style>
circle {
fill: steelblue;
}
body {
font: 12px Arial;
}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
div.tooltip {
position: absolute;
text-align: center;
width: 80px;
height: 64px;
padding: 2px;
font: 14px sans-serif;
color: black;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
.overlay {
fill: none;
pointer-events: all;
}
.focus circle {
fill: #F1F3F3;
stroke: #6F257F;
stroke-width: 5px;
}
.hover-line {
stroke: #6F257F;
stroke-width: 2px;
stroke-dasharray: 3, 3;
}
</style>
</head>
<body>
<svg class='line-chart2'></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="./regression.js"></script>
</body>
regression.js
var gdp = [387.65, 410.32, 415.73, 452.69, 462.14,
478.96, 508.06, 599.59, 699.68, 808.90,
920.31, 1201.11, 1186.95, 1323.94, 1656.61,
1823.04, 1827.63, 1856.72, 2039.12, 2102.39,
2274.22, 2600.81
]; //y or GDP of India
var years = ['1996', '1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017'];
var data_gdp = []
for (i = 0; i < years.length; i++) {
data_gdp.push({
year: years[i],
value: gdp[i]
})
}
function drawChart_gdp(data, class_name) {
var svgWidth = 1200,
svgHeight = 400;
var margin = {
top: 60,
right: 60,
bottom: 60,
left: 60
};
var width = svgWidth - margin.left - margin.right;
var height = svgHeight - margin.top - margin.bottom;
var svg = d3.select(class_name)
.attr("width", svgWidth)
.attr("height", svgHeight);
var bisectDate = d3.bisector(function(d) {
return d.year;
}).left;
var g = svg.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")"
);
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().rangeRound([height, 0]);
var line = d3.line()
.x(function(d) {
return x(new Date(parseInt(d.year), 0))
})
.y(function(d) {
return y(d.value)
})
x.domain(d3.extent(data, function(d) {
return new Date(parseInt(d.year), 0);
}));
y.domain(d3.extent(data, function(d) {
return d.value
}));
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.append("text")
.attr("fill", "#000")
.text("Year")
.attr("dy", "1.90em")
.attr("y", 5)
.attr("x", 500)
.attr("font-size", "20px")
.select(".domain")
.remove();
g.append("g")
.call(d3.axisLeft(y))
.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", -80)
.attr("x", -55)
.attr("dy", "1.90em")
.attr("text-anchor", "center")
.attr("font-size", "20px")
.text("GDP ($)")
g.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 1.5)
.attr("d", line);
var focus = g.append("g")
.attr("class", "focus")
.style("display", "none");
focus.append("line")
.attr("class", "x-hover-line hover-line")
.attr("y1", 0)
.attr("y2", height);
focus.append("line")
.attr("class", "y-hover-line hover-line")
.attr("x1", width)
.attr("x2", width);
focus.append("circle")
.attr("r", 7.5);
focus.append("text")
.attr("x", 15)
.attr("dy", ".31em");
svg.append("rect")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height)
.on("mouseover", function() {
focus.style("display", null);
})
.on("mouseout", function() {
focus.style("display", "none");
})
.on("mousemove", function() { //problem in this function
var x0 = d3.timeFormat("%Y")(x.invert(d3.mouse(this)[0])),
i = bisectDate(data, x0, 1);
d0 = data[i - 1],
d1 = data[i],
d = x0 - d0.year > d1.year - x0 ? d1 : d0;
focus.attr("transform", "translate(" + x(d.year) + "," + y(d.value) + ")");
focus.select("text").text(function() {
return d.value;
});
focus.select(".x-hover-line").attr("y2", height - y(d.value));
focus.select(".y-hover-line").attr("x2", width + width);
});
}
drawChart_gdp(data_gdp, '.line-chart2');
I am suspecting that in the example the data is being pulled from json file but here is pulled from an array where the problem comes for and also I think the kind of data is little bit different too. My goals is just to create a circle tool which shows the value of y-axis.
The problem you're facing now is almost the opposite of the one you faced in your previous question: in that question, the problem was that you were dealing with date objects as if they were strings.
Now, you're dealing with strings as if they were date objects. In your data, the year is just a string, like "1996".
So, this:
focus.attr("transform", "translate(" + x(d.year) + "," + y(d.value) + ")");
Should be:
focus.attr("transform", "translate(" + x(d3.timeParse("%Y")(d.year)) + "," + y(d.value) + ")");
//parsing to a date here----------------------^
Here is the code with that change:
var gdp = [387.65, 410.32, 415.73, 452.69, 462.14,
478.96, 508.06, 599.59, 699.68, 808.90,
920.31, 1201.11, 1186.95, 1323.94, 1656.61,
1823.04, 1827.63, 1856.72, 2039.12, 2102.39,
2274.22, 2600.81
]; //y or GDP of India
var years = ['1996', '1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017'];
var data_gdp = []
for (i = 0; i < years.length; i++) {
data_gdp.push({
year: years[i],
value: gdp[i]
})
}
function drawChart_gdp(data, class_name) {
var svgWidth = 1200,
svgHeight = 400;
var margin = {
top: 60,
right: 60,
bottom: 60,
left: 60
};
var width = svgWidth - margin.left - margin.right;
var height = svgHeight - margin.top - margin.bottom;
var svg = d3.select(class_name)
.attr("width", svgWidth)
.attr("height", svgHeight);
var bisectDate = d3.bisector(function(d) {
return d.year;
}).left;
var g = svg.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")"
);
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().rangeRound([height, 0]);
var line = d3.line()
.x(function(d) {
return x(new Date(parseInt(d.year), 0))
})
.y(function(d) {
return y(d.value)
})
x.domain(d3.extent(data, function(d) {
return new Date(parseInt(d.year), 0);
}));
y.domain(d3.extent(data, function(d) {
return d.value
}));
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.append("text")
.attr("fill", "#000")
.text("Year")
.attr("dy", "1.90em")
.attr("y", 5)
.attr("x", 500)
.attr("font-size", "20px")
.select(".domain")
.remove();
g.append("g")
.call(d3.axisLeft(y))
.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", -80)
.attr("x", -55)
.attr("dy", "1.90em")
.attr("text-anchor", "center")
.attr("font-size", "20px")
.text("GDP ($)")
g.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 1.5)
.attr("d", line);
var focus = g.append("g")
.attr("class", "focus")
.style("display", "none");
focus.append("line")
.attr("class", "x-hover-line hover-line")
.attr("y1", 0)
.attr("y2", height);
focus.append("line")
.attr("class", "y-hover-line hover-line")
.attr("x1", width)
.attr("x2", width);
focus.append("circle")
.attr("r", 7.5);
focus.append("text")
.attr("x", 15)
.attr("dy", ".31em");
svg.append("rect")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height)
.on("mouseover", function() {
focus.style("display", null);
})
.on("mouseout", function() {
focus.style("display", "none");
})
.on("mousemove", function() { //problem in this function
var x0 = d3.timeFormat("%Y")(x.invert(d3.mouse(this)[0])),
i = bisectDate(data, x0, 1);
d0 = data[i - 1],
d1 = data[i],
d = x0 - d0.year > d1.year - x0 ? d1 : d0;
focus.attr("transform", "translate(" + x(d3.timeParse("%Y")(d.year)) + "," + y(d.value) + ")");
focus.select("text").text(function() {
return d.value;
});
focus.select(".x-hover-line").attr("y2", height - y(d.value));
focus.select(".y-hover-line").attr("x2", width + width);
});
}
drawChart_gdp(data_gdp, '.line-chart2');
<head>
<style>
circle {
fill: steelblue;
}
body {
font: 12px Arial;
}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
div.tooltip {
position: absolute;
text-align: center;
width: 80px;
height: 64px;
padding: 2px;
font: 14px sans-serif;
color: black;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
.overlay {
fill: none;
pointer-events: all;
}
.focus circle {
fill: #F1F3F3;
stroke: #6F257F;
stroke-width: 5px;
}
.hover-line {
stroke: #6F257F;
stroke-width: 2px;
stroke-dasharray: 3, 3;
}
</style>
</head>
<body>
<svg class='line-chart2'></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
</body>
As you know by now, all this confusion comes to the fact that you have strings in your data array, but x is a time scale. My advice: parse the strings in your data array, creating date objects, and be consistent in your code, dealing all data as date objects, not strings.
Below is my line graph where I am using 2 lines to show different values,
One line is blue and the other is red.
however the red line i want to start from 'Dec 27'(half way of the graph) instead of the start of the graph. I have been looking ways to do this but honestly I'm not sure how I can.
if someone is able to show me how i would appreciate that a lot.
Thanks you in advance!
This is my css:
path.line {
fill: none;
stroke: #004ecc;
stroke-width: 4px;
}
path.line2 {
fill: none;
stroke: #cc0000;
stroke-width: 4px;
}
path.area {
fill: #e7e7e7;
}
.guideline {
margin-right: 100px;
float: right;
}
.axis path,
.axis line {
fill: none;
stroke-width: 5px;
}
.x.axis path {
display: none;
}
.y.axis path {
display: none;
}
.grid .tick {
stroke: black;
stroke-width: 0.2px;
opacity: 5;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
.graph-column {
float: left;
}
.tablebad thead tr {
background-color: #eee;
}
.tablegood thead tr th {
background-color: #eee;
}
This is my d3.js:
<script>
var margin = {
top: 0,
right: 90,
bottom: 30,
left: 50
},
width = 1200 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
padding = 1;
var parseDate = d3.time.format("%d-%b-%y").parse;
// Set the ranges
var x = d3.time.scale()
.range([10, width - 15]);
var x2 = d3.scale.ordinal().rangePoints([10, width], .10)
var y = d3.scale.linear()
.range([height, 100]);
var xAxis = d3.svg.axis().scale(x2)
.orient("bottom")
.tickFormat(d3.time.format("%b %d"))
.ticks(4)
.tickPadding(2);
var yAxis = d3.svg.axis().scale(y)
.orient("left");
var valueline = d3.svg.line()
.interpolate("basis")
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.XMAS);
});
var valueline2 = d3.svg.line()
.interpolate("basis")
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.JANSALES);
});
//florida
var chart1 = d3.select("#LineChart")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//needed for the grid
function make_y_axis() {
return d3.svg.axis()
.scale(y)
.orient("left")
}
data1 = [{
"date": "24-Dec-12",
"XMAS": 2,
"JANSALES": 0
}, {
"date": "25-Dec-12",
"XMAS": 3,
"JANSALES": 0
},
{
"date": "26-Dec-12",
"XMAS": 1,
"JANSALES": 0
},
{
"date": "27-Dec-12",
"XMAS": 2.0,
"JANSALES": 0
},
{
"date": "28-Dec-12",
"XMAS": 4.0,
"JANSALES": 0
},
{
"date": "29-Dec-12",
"XMAS": 4.0,
"JANSALES": 0
}
,
{
"date": "29-Dec-12",
"XMAS": 5,
"JANSALES": 0
},
{
"date": "30-Dec-12",
"JANSALES": 3.0
},
{
"date": "31-Dec-12",
"JANSALES": 2.0
},
{
"date": "01-Jan-13",
"JANSALES": 3.0
},
{
"date": "02-Jan-13",
"JANSALES": 1.0
},
{
"date": "03-Jan-13",
"JANSALES": 3.0
},
{
"date": "04-Jan-13",
"JANSALES": 2.0
},
{
"date": "05-Jan-13",
"JANSALES": 2.0
},
{
"date": "06-Jan-13",
"JANSALES": 1.0
},
{
"date": "07-Jan-13",
"JANSALES": 2.0
},
{
"date": "08-Jan-13",
"JANSALES": 2.0
},
{
"date": "09-Jan-13",
"JANSALES": 3.0
},
{
"date": "10-Jan-13",
"JANSALES": 2.0
},
{
"date": "11-Jan-13",
"JANSALES": 3.0
},
{
"date": "12-Jan-13",
"JANSALES": 3.0
},
{
"date": "13-Jan-13",
"JANSALES": 2.0
},
{
"date": "14-Jan-13",
"JANSALES": 1.0
}
];
var color = d3.scale.ordinal().range(["#004ecc", "#cc0000"]);
//d3.csv("data.csv", function(error, data) {
data1.forEach(function(d) {
d.date = parseDate(d.date);
d.XMAS = +d.XMAS;
d.JANSALES = +d.JANSALES;
});
// Scale the range of the data
x.domain(d3.extent(data1, function(d) {
return d.date;
}));
y.domain([0, 10]);
x2.domain(data1.map(function(d) {
return d.date;
}));
//add the grid
chart1.append("g")
.attr("class", "grid")
.call(make_y_axis()
.tickSize(-width, 0, 0)
.tickFormat("")
)
chart1.append("path")
.attr("class", "line")
.attr("stroke", "red")
.attr("d", valueline(data1));
chart1.append("path")
.attr("class", "line2")
.attr("d", valueline2(data1.filter(function(d) {
return d.date > parseDate("29-Dec-12");
})));
// Add the X Axis
chart1.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
chart1.append("g")
.attr("class", "y axis")
.call(yAxis);
chart1.append("text")
.attr("transform", "translate(" + (width + 3) + "," + y(data1[0].JANSALES) + ")")
.attr("x", ".1em")
.attr("y", "-40")
.attr("text-anchor", "start")
.style("fill", "red")
.style("font-size", "15")
.style("font-weight", "bold")
.text("JAN SALES");
chart1.append("text")
.attr("transform", "translate(" + (width + 3) + "," + y(data1[0].XMAS) + ")")
.attr("x", ".1em")
.attr("y", "10")
.attr("text-anchor", "start")
.style("fill", "steelblue")
.style("font-size", "15")
.style("font-weight", "bold")
.text("XMAS");
//plus 1: animation
var curtain = chart1.append('rect')
.attr('x', -1 * width)
.attr('y', -1 * height - 2)
.attr('height', height)
.attr('width', width)
.attr('class', 'curtain')
.attr('transform', 'rotate(180)')
.style('fill', '#ffffff')
/* Optionally add a guideline */
var guideline = chart1.append('line')
.attr('stroke', '#333')
.attr('stroke-width', 0.4)
.attr('class', 'guide')
.attr('x1', 1)
.attr('y1', 1)
.attr('x2', 1)
.attr('y2', height)
var t = chart1.transition()
.delay(120)
.duration(500)
.ease('linear')
.each('end', function() {
d3.select('line.guide')
.transition()
.style('opacity', 0)
.remove()
});
t.select('rect.curtain')
.attr('width', 0);
t.select('line.guide')
.attr('transform', 'translate(' + width + ', 0)')
d3.select("#show_guideline").on("change", function(e) {
});
</script>
And finally this is my Div tag where i am calling out the d3.js:
<div id="florida"></div>
Right now the blue line and the red line use the same data set.
If you want the red line using a different data set, you can filter out the unwanted objects:
.attr("d", valueline2(data1.filter(function(d) {
return d.date > parseDate("26-Dec-12");
})));
Here is your code with that change:
var margin = {
top: 30,
right: 100,
bottom: 30,
left: 50
},
width = 800 - margin.left - margin.right,
height = 280 - margin.top - margin.bottom,
padding = 1;
var parseDate = d3.time.format("%d-%b-%y").parse;
// Set the ranges
var x = d3.time.scale()
.range([10, width - 15]);
var x2 = d3.scale.ordinal().rangePoints([0, width], .25)
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis().scale(x2)
.orient("bottom")
.tickFormat(d3.time.format("%b %d"))
.ticks(4)
.tickPadding(2);
var yAxis = d3.svg.axis().scale(y)
.orient("left");
var valueline = d3.svg.line()
.interpolate("basis")
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.trump);
});
var valueline2 = d3.svg.line()
.interpolate("basis")
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.clinton);
});
//florida
var chart1 = d3.select("#florida")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//needed for the grid
function make_y_axis() {
return d3.svg.axis()
.scale(y)
.orient("left")
}
data1 = [{
"date": "24-Dec-12",
"trump": 2.0,
"clinton": 0
}, {
"date": "25-Dec-12",
"trump": 3.0,
"clinton": 0
},
{
"date": "26-Dec-12",
"trump": 1.0,
"clinton": 2
},
{
"date": "27-Dec-12",
"trump": 2.0,
"clinton": 0
},
{
"date": "28-Dec-12",
"trump": 4.0,
"clinton": 0
}
,
{
"date": "29-Dec-12",
"trump": 1.0,
"clinton": null
}
];
var color = d3.scale.ordinal().range(["#004ecc", "#cc0000"]);
//d3.csv("data.csv", function(error, data) {
data1.forEach(function(d) {
d.date = parseDate(d.date);
d.trump = +d.trump;
d.clinton = +d.clinton;
});
// Scale the range of the data
x.domain(d3.extent(data1, function(d) {
return d.date;
}));
y.domain([0, 5]);
x2.domain(data1.map(function(d) {
return d.date;
}));
//add the grid
chart1.append("g")
.attr("class", "grid")
.call(make_y_axis()
.tickSize(-width, 0, 0)
.tickFormat("")
)
chart1.append("path")
.attr("class", "line")
.attr("stroke", "red")
.attr("d", valueline(data1));
chart1.append("path")
.attr("class", "line2")
.attr("d", valueline2(data1.filter(function(d) {
return d.date > parseDate("26-Dec-12");
})));
// Add the X Axis
chart1.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
chart1.append("g")
.attr("class", "y axis")
.call(yAxis);
chart1.append("text")
.attr("transform", "translate(" + (width + 3) + "," + y(data1[0].clinton) + ")")
.attr("x", ".1em")
.attr("y", "-40")
.attr("text-anchor", "start")
.style("fill", "red")
.style("font-size", "15")
.style("font-weight", "bold")
.text("JAN SALES");
chart1.append("text")
.attr("transform", "translate(" + (width + 3) + "," + y(data1[0].trump) + ")")
.attr("x", ".1em")
.attr("y", "10")
.attr("text-anchor", "start")
.style("fill", "steelblue")
.style("font-size", "15")
.style("font-weight", "bold")
.text("XMAS");
//plus 1: animation
var curtain = chart1.append('rect')
.attr('x', -1 * width)
.attr('y', -1 * height - 2)
.attr('height', height)
.attr('width', width)
.attr('class', 'curtain')
.attr('transform', 'rotate(180)')
.style('fill', '#ffffff')
/* Optionally add a guideline */
var guideline = chart1.append('line')
.attr('stroke', '#333')
.attr('stroke-width', 0.4)
.attr('class', 'guide')
.attr('x1', 1)
.attr('y1', 1)
.attr('x2', 1)
.attr('y2', height)
var t = chart1.transition()
.delay(120)
.duration(500)
.ease('linear')
.each('end', function() {
d3.select('line.guide')
.transition()
.style('opacity', 0)
.remove()
});
t.select('rect.curtain')
.attr('width', 0);
t.select('line.guide')
.attr('transform', 'translate(' + width + ', 0)')
d3.select("#show_guideline").on("change", function(e) {
guideline.attr('stroke-width', this.checked ? 1 : 0);
curtain.attr("opacity", this.checked ? 0.75 : 1);
});
path.line {
fill: none;
stroke: #004ecc;
stroke-width: 4px;
}
path.line2 {
fill: none;
stroke: #cc0000;
stroke-width: 4px;
}
path.area {
fill: #e7e7e7;
}
.guideline {
margin-right: 100px;
float: right;
}
.axis path,
.axis line {
fill: none;
stroke-width: 5px;
}
.x.axis path {
display: none;
}
.y.axis path {
display: none;
}
.grid .tick {
stroke: black;
stroke-width: 0.2px;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="florida"></div>
This is only one of the ways to do it. There are another approaches, such as using line.defined and null values.
Right now i have a brush function and two lines. I could add tiptool without brush function but since i have brush now, it wont focus anymore. And also i have two lines, so its hard to choose a appropriate tiptool. I wanted to add the tiptool only on the upper margin. I am new in javascript. Anyone could help me with it? Thank you so much
var margin = {
top: 10,
right: 10,
bottom: 100,
left: 40
},
margin2 = {
top: 430,
right: 10,
bottom: 20,
left: 40
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
height2 = 500 - margin2.top - margin2.bottom;
var color = d3.scale.category10();
var parseDate = d3.time.format("%m/%e/%Y %H:%M").parse;
var x = d3.time.scale().range([0, width]),
x2 = d3.time.scale().range([0, width]),
y = d3.scale.linear().range([height, 0]),
y2 = d3.scale.linear().range([height2, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom"),
xAxis2 = d3.svg.axis().scale(x2).orient("bottom"),
yAxis = d3.svg.axis().scale(y).orient("left");
var brush = d3.svg.brush()
.x(x2)
.on("brush", brush);
var line = d3.svg.line()
.defined(function(d) {
return !isNaN(d.power);
})
.interpolate("cubic")
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.power);
});
var line2 = d3.svg.line()
.defined(function(d) {
return !isNaN(d.power);
})
.interpolate("cubic")
.x(function(d) {
return x2(d.date);
})
.y(function(d) {
return y2(d.power);
});
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var context = svg.append("g")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
d3.csv("pvdata2.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) {
return key !== "pvdate";
}));
data.forEach(function(d) {
d.date = parseDate(d.pvdate);
});
var sources = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {
date: d.date,
power: +d[name]
};
})
};
});
x.domain(d3.extent(data, function(d) {
return d.date;
}));
y.domain([d3.min(sources, function(c) {
return d3.min(c.values, function(v) {
return v.power;
});
}),
d3.max(sources, function(c) {
return d3.max(c.values, function(v) {
return v.power;
});
})
]);
x2.domain(x.domain());
y2.domain(y.domain());
var focuslineGroups = focus.selectAll("g")
.data(sources)
.enter().append("g");
var focuslines = focuslineGroups.append("path")
.attr("class", "line")
.attr("d", function(d) {
return line(d.values);
})
.style("stroke", function(d) {
return color(d.name);
})
.attr("clip-path", "url(#clip)");
focus.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
focus.append("g")
.attr("class", "y axis")
.call(yAxis);
var contextlineGroups = context.selectAll("g")
.data(sources)
.enter().append("g");
var contextLines = contextlineGroups.append("path")
.attr("class", "line")
.attr("d", function(d) {
return line2(d.values);
})
.style("stroke", function(d) {
return color(d.name);
})
.attr("clip-path", "url(#clip)");
context.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height2 + ")")
.call(xAxis2);
context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", height2 + 7);
svg.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", 45)
.attr("dy", "0.71em")
.style("text-anchor", "end")
.text("Power (kW)");
});
function brush() {
x.domain(brush.empty() ? x2.domain() : brush.extent());
focus.selectAll("path.line").attr("d", function(d) {
return line(d.values)
});
focus.select(".x.axis").call(xAxis);
focus.select(".y.axis").call(yAxis);
}
// Active point element
var activePoint = svg.append('circle')
.attr({
cx: 0,
cy: 0,
r: 5,
'pointer-events': 'none'
})
.style({
stroke: 'none',
fill: 'red',
'fill-opacity': 0
});
svg {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.y.axis path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.brush .extent {
stroke: #fff;
fill-opacity: .125;
shape-rendering: crispEdges;
}
.line {
fill: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
I want ticks to come above shaded region in graph, i have tried transparency but it will not work.
Due to some constraint i cannot change the way i am coloring green region, but its like this-> Shade area below above line with green, then area below bottom line as white(same as chart background color)
Now due to this, ticks are hiding behind, is there a way i can place them above? or redraw new ticks in shaded region?
Click here for image of graph
renderGraph: function(){
// Data notice the structure
//************************************************************
var data = [
[{'x':1,'y':7},{'x':2,'y':7},{'x':3,'y':7},{'x':4,'y':7},{'x':4.5,'y':8.1},{'x':6.3,'y':8.1},{'x':6.8,'y':7},{'x':8,'y':7},{'x':9,'y':8},{'x':10,'y':8}],
[{'x':1,'y':9},{'x':2,'y':8},{'x':3,'y':11},{'x':4,'y':10},{'x':5,'y':10},{'x':6,'y':9},{'x':7,'y':10},{'x':8,'y':10},{'x':9,'y':11},{'x':10,'y':10}],
[{'x':1,'y':9.5},{'x':2,'y':9},{'x':3,'y':10.5},{'x':4,'y':9},{'x':5,'y':10},{'x':6,'y':9},{'x':7,'y':11},{'x':8,'y':10},{'x':9,'y':11},{'x':10,'y':11}],
[{'x':1,'y':8},{'x':2,'y':8},{'x':3,'y':8},{'x':4,'y':8},{'x':5,'y':10},{'x':6,'y':10},{'x':7,'y':8},{'x':8,'y':8},{'x':9,'y':9},{'x':10,'y':9}],
[{'x':1,'y':10},{'x':2,'y':10},{'x':3,'y':10},{'x':4,'y':11},{'x':5,'y':11},{'x':6.5,'y':11},{'x':7,'y':10},{'x':8,'y':10},{'x':9,'y':11},{'x':10,'y':11}]
];
var dataAboveLine = [{'x':1,'y':10},{'x':2,'y':10},{'x':3,'y':10},{'x':4,'y':11},{'x':5,'y':11},{'x':6.5,'y':11},{'x':7,'y':10},{'x':8,'y':10},{'x':9,'y':11},{'x':10,'y':11}];
var dataBelowLine = [{'x':1,'y':7},{'x':2,'y':7},{'x':3,'y':7},{'x':4,'y':7},{'x':4.5,'y':8.1},{'x':6.3,'y':8.1},{'x':6.8,'y':7},{'x':8,'y':7},{'x':9,'y':8},{'x':10,'y':8}];
var colors = [
'steelblue',
'RGB(0,93,135)',
'RGB(226,0,26)',
'RGB(142,166,78)'
]
var lineType = [
'0 1', //5 0
'5 0',
'5 0',
'8 5'
]
//************************************************************
// Create Margins and Axis and hook our zoom function
//************************************************************
var margin = {top: 20, right: 30, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, 12])
.range([0, width]);
var y = d3.scale.linear()
.domain([-1, 16])
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
//.tickSize(-height)
.tickPadding(10)
.tickSubdivide(true)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.tickPadding(10)
.tickSize(-width)
.tickSubdivide(true)
.orient("left");
var area = d3.svg.area()
.x(function(d) { return x(d.x); })
.y0(height)
.y1(function(d) { return y(d.y); });
var zoom = d3.behavior.zoom()
.x(x)
.y(y)
.scaleExtent([1, 3])
.on("zoom", zoomed);
var vertical = d3.select("#chartHolder")
.append("div")
.attr("clip-path", "url(#clip)")
.attr("class", "remove")
.style("position", "absolute")
.style("z-index", "19")
.style("width", "1px")
.style("height", "450px")
// .style("top", "39px")
.style("top", "46px")
.style("bottom", "1px")
.style("left", "8px")
.style("background", "#000");
var horizontal = d3.select("#chartHolder")
.append("div")
.attr("clip-path", "url(#clip)")
.attr("class", "remove")
.style("position", "absolute")
.style("z-index", "19")
.style("width", "881px")
.style("height", "1px")
.style("top", "47px")
.style("bottom", "1px")
.style("left", "57px")
.style("background", "#000");
//************************************************************
// Generate our SVG object
//************************************************************
var svg = d3.select("#chartHolder").append("svg")
.call(zoom)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("class", "svgClass")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
// svg.append("g")
// .attr("class", "x axis")
// .append("text")
// .attr("class", "axis-label")
// .attr("y", 500)
// .attr("x", 400)
// .text('new');
svg.append("g")
.attr("class", "y axis")
.append("text")
.attr("class", "axis-label")
.attr("transform", "rotate(-90)")
.attr("y", (-margin.left) + 10)
.attr("x", -height/2)
.text('Hours');
svg.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
svg.append("path")
.datum(dataAboveLine)
.attr("class", "areaAbove")
.attr("d", area)
.attr("clip-path", "url(#clip)");
svg.append("path")
.datum(dataBelowLine)
.attr("class", "areaBelow")
.attr("d", area)
.attr("clip-path", "url(#clip)");
//************************************************************
// Create D3 line object and draw data on our SVG object
//************************************************************
var line = d3.svg.line()
.interpolate("linear")
.x(function(d) { return x(d.x); })
.y(function(d) { return y(d.y); });
svg.selectAll('.line')
.data(data)
.enter()
.append("path")
.attr("class", "line")
.attr("clip-path", "url(#clip)")
.attr('stroke', function(d,i){
return colors[i%colors.length];
})
.style("stroke-dasharray", function(d,i){
return lineType[i%lineType.length];
})
.attr("d", line)
.attr("stroke-width","3px");
// Define the div for the tooltip
var div = d3.select("#chartHolder").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
//************************************************************
// Draw points on SVG object based on the data given
//************************************************************
var points = svg.selectAll('.dots')
.data(data)
.enter()
.append("g")
.attr("class", "dots")
.attr("clip-path", "url(#clip)");
points.selectAll('.dot')
.data(function(d, index){
var a = [];
d.forEach(function(point,i){
a.push({'index': index, 'point': point});
});
return a;
})
.enter()
.append('circle')
.on("click", function(d){click(d)})
.attr('class','dot')
.attr("r", 3.5)
.attr('fill', function(d,i){
return colors[d.index%colors.length];
})
.attr('fill-opacity', function(d,i){
if(d.index==0||d.index==4||d.index==3){
return '0';
}
})
.attr("transform", function(d) {
return "translate(" + x(d.point.x) + "," + y(d.point.y) + ")"; }
)
.on("mouseover", function(d) {
div.transition()
// .duration(200)
.style("opacity", .9);
div .html("X:"+d.point.x + "<br/>" +"Y:"+ d.point.y)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
// .duration(500)
.style("opacity", 0);
});
function click(d){
alert(JSON.stringify(d.point));
}
//************************************************************
// Zoom specific updates
//************************************************************
function zoomed() {
svg.select(".areaAbove").call(area);
svg.select(".x.axis").call(xAxis);
svg.select(".y.axis").call(yAxis);
svg.selectAll('path.line').attr('d', line);
svg.select('.areaAbove').attr('d', area);
svg.select('.areaBelow').attr('d', area);
points.selectAll('circle').attr("transform", function(d) {
return "translate(" + x(d.point.x) + "," + y(d.point.y) + ")"; }
);
}
var txtCycle = d3.select("#chartHolder").append("p")
.append("text")
.attr("class", "yaxis-label")
.attr("y", 463)
.attr("x", 400)
.text('Number of cycles');
var slider = d3.select("#chartHolder").append("p").append("input")
.datum({})
.attr("type", "range")
.attr("class","slider")
.attr("value", zoom.scaleExtent()[0])
.attr("min", zoom.scaleExtent()[0])
.attr("max", zoom.scaleExtent()[1])
.attr("step", (zoom.scaleExtent()[1] - zoom.scaleExtent()[0]) / 100)
.on("input", slided);
var svgimg = document.createElementNS('http://www.w3.org/2000/svg','image');
svgimg.setAttributeNS(null,'height','22');
svgimg.setAttributeNS(null,'width','350');
svgimg.setAttributeNS('http://www.w3.org/1999/xlink','href', 'xaxis.PNG');
svgimg.setAttributeNS(null,'x','580');
svgimg.setAttributeNS(null,'y','450');
svgimg.setAttributeNS(null, 'visibility', 'visible');
$('svg').append(svgimg);
function slided(d){
zoom.scale(d3.select(this).property("value"))
.event(svg);
}
//for crosshairs
d3.select("#chartHolder")
.on("mousemove", function(){
coord = d3.mouse(this);
mousex = coord[0];
mousey=coord[1];
// vertical.style("left", mousex+ "px" );
// horizontal.style("top", mousey +"px")
if((mousex+6)>935){
mousex=929;
}
if((mousex+6)<59){
mousex=53;
}
if((mousey+6)>495){
mousey=489;
}
if((mousey+6)<44){
mousey=39;
}
vertical.style("left", mousex+6+ "px" );
horizontal.style("top", mousey+6 +"px");
})
.on("mouseover", function(){
coord = d3.mouse(this);
mousex = coord[0];
mousey=coord[1];
if((mousex+6)>930){
mousex=924;
}
if((mousex+6)<51){
mousex=45;
}
if((mousey+6)<39){
mousey=33;
}
if((mousey+6)>487){
mousey=481;
}
// vertical.style("left", mousex + "px");
// horizontal.style("top", mousey +"px")});
vertical.style("left", mousex +6+ "px");
horizontal.style("top", mousey +6+"px")});
// add cross hairs and floating value on axis
/*
var chart = d3.select("svg");
var focusText = chart.append("g")
.attr("class","focus")
.style("display", "none");
focusText.append("text").attr({"x": 9, "dy": "0.35em"});
var focus = chart.append("g")
.attr("class","focus")
.style("display", "none");
//focus.append("text").attr({"x": 9, "dy": "0.35em"});
// horizontal crosshair
focus.append("line")
.attr({
"x1": -width,
"y1": 0,
"x2": width,
"y2": 0
});
// vertical crosshair
focus.append("line")
.attr({
"x1": 0,
"y1": -height,
"x2": 0,
"y2": height
});
chart.append("rect")
.attr({"class": "overlay" , "width": width , "height": height})
.on({
"mouseover": function() { focus.style("display", null); focusText.style("display", null); },
"mouseout": function() { focus.style("display", "none"); focusText.style("display", "none"); },
"mousemove": mousemove
});
function mousemove() {
var x0 = xScale.invert(d3.mouse(this)[0]),
i = bisectDate(sample2, x0, 1),
d0 = sample2[i-1],
d1 = sample2[i],
d = x0 - d0.date > d1.date - x0 ? d1 : d0;
focus.attr("transform", "translate(" + (d3.mouse(this)[0]) + "," + yScale(d.close) + ")");
focusText.attr("transform", "translate(" + (width-margin.right) + "," + yScale(d.close) + ")");
focusText.select("text").text("$" + d.close);
} */
//
}
renderGraph();
.sapUiBody{
background-color: white;
background-image: none;
}
.grid .tick {
stroke: lightgrey;
opacity: 0.7;
shape-rendering: crispEdges;
}
.grid path {
stroke-width: 0;
}
.axis path {
fill: none;
stroke: #bbb;
shape-rendering: crispEdges;
}
.axis text {
fill: #555;
}
.axis line {
stroke: #e7e7e7;
shape-rendering: crispEdges;
}
.axis .axis-label {
font-size: 14px;
}
.yaxis-label{
left: 448px;
position: absolute;
display: block;
}
.line {
fill: none;
stroke-width: 2.0px;
}
.dot {
/* consider the stroke-with the mouse detect radius? */
stroke: transparent;
stroke-width: 10px;
cursor: pointer;
}
div.tooltip {
position: absolute;
text-align: center;
width: 60px;
height: 28px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
.areaBelow {
fill: white;
stroke-width: 0;
}
.areaAbove {
fill: RGB(142,166,78);
stroke-width: 0;
opacity: 0.34;
}
.dot:hover {
stroke: rgba(68, 127, 255, 0.3);
}
.slider{
width: 300px;
}
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>
I am having some issues with tooltips for my bar graph. For each stopname column, there should be a corresponding value of boarding and alightings shown in the tooltip, however, I am getting undefined values like here
Here is my code:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: orange;
}
.bar:hover {
fill: orangered ;
}
.x.axis path {
display: none;
}
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
content: "\25BC";
position: absolute;
text-align: center;
}
/* Style northward tooltips differently */
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>
var margin = {top: 40, right: 20, bottom: 300, left: 40},
width = 1250 - margin.left - margin.right,
height = 750 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.range(["orange", "orangered"]);
var xAxis = d3.svg.axis()
.scale(x0)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Stop:</strong> <span style='color:red'>" + d.stopname + "</span>" + "<br><br><strong>Mean no. of boardings:</strong> <span style='color:red'>" + d.meanboardings + "</span>"+ "<br><br><strong>Mean no. of alightings:</strong> <span style='color:red'>" + d.meanalightings + "</span>";
})
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.call(tip);
d3.tsv("data.tsv", function(d){
return {
stopname: d.stopname,
meanboardings: +d.meanboardings,
meanalightings: +d.meanalightings
};
}, function(error, data) {
console.log(data);
var dataset = d3.keys(data[0]).filter(function(key) { return key !== "stopname"
});
data.forEach(function(d) {
d.passengers = dataset.map(function(name) { return {name: name, value: +d[name]}; });
});
x0.domain(data.map(function(d) { return d.stopname; }));
x1.domain(dataset).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(data, function(d) { return d3.max(d.passengers, function(d) { return d.value; }); })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.5em")
.attr("transform", function(d) {
return "rotate(-90)"
});
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Mean no. of boardings and alightings");
var stopname = svg.selectAll(".stopname")
.data(data)
.enter().append("g")
.attr("class", "stopname")
.attr("transform", function(d) { return "translate(" + x0(d.stopname) + ",0)"; });
stopname.selectAll("rect")
.data(function(d) { return d.passengers; })
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function(d) { return x1(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.style("fill", function(d) { return color(d.name); })
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
var legend = svg.selectAll(".legend")
.data(dataset.slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.name); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
});
function type(d) {
d.data = +d.data;
return d;
}
</script>
TSV file:
stopname maxboardings meanboardings minboardings varboardings maxalightings meanalightings minalightings varalightings maxload meanload minload varload noofbuses
The Boardwalk Terminal (3908) 7 2.571428571 0 6.952380952 0 0 0 0 7 2.571428571 0 6.952380952 7
Highview / Sugar Maple (3329) 2 0.333333333 0 0.666666667 1 0.166666667 0 0.166666667 6 3 0 6.4 6
Highview / Highview Pl (3330) 0 0 0 0 1 0.166666667 0 0.166666667 5 2.833333333 0 5.366666667 6
....
Any help is appreciated, thank you!
You are getting undefined because you are using an undefined value for generating tooltip text.
In your html function, the data-object associated d you get for every rectangle/bar is of following format:
{name: "meanlightings", value: <some_value>}
It does not contain the stopname property and will only contain value for one of the fields in the original dataset.
You will have to rewrite the html callback as
.html(function(d) {
return "<strong>" + d.name + " :</strong> <span style='color:red'>" + d.value + "</span>";
})
However, if you want to show more properties, you will have to change the data that you are binding to rectangles.