xxxxxxxxxx
<meta charset="utf-8">
<head>
<title>Chandrakant Bharatkumar Thakkar</title>
</head>
<body>
<div id="charts">
<svg width="800" height="500"></svg>
</div>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
function createChartLegend(mainDiv, group) {
var z = d3.scaleOrdinal(d3.schemeCategory10);
var mainDivName = mainDiv.substr(1, mainDiv.length);
$(mainDiv).before("<div id='Legend_" + mainDivName + "' class='pmd-card-body' style='margin-top:0; margin-bottom:0;'></div>");
var keys = group;
keys.forEach(function(d) {
var cloloCode = z(d);
$("#Legend_" + mainDivName).append("<span class='team-graph team1' style='display: inline-block; margin-right:10px;'>\
<span style='background:" + cloloCode +
";width: 10px;height: 10px;display: inline-block;vertical-align: middle;'> </span>\
<span style='padding-top: 0;font-family:Source Sans Pro, sans-serif;font-size: 13px;display: inline;'>" + d +
" </span>\
</span>");
});
}
var group = ["Laptops", "Processor", "Ram"];
var parseDate = d3.timeFormat("%b-%Y");
var mainDiv = "#charts";
var mainDivName = "charts";
createChartLegend(mainDiv, group);
var salesData = [{
'date': '2017-06-30T18:30:00.000Z',
'Ram': 359,
'Laptops': 0,
'Processor': 23
}, {
'date': '2017-07-31T18:30:00.000Z',
'Ram': 828,
'Laptops': 1,
'Processor': 30
},
{
'date': '2017-08-31T18:30:00.000Z',
'Ram': 788,
'Laptops': 81,
'Processor': 70
}, {
'date': '2017-09-30T18:30:00.000Z',
'Ram': 503,
'Laptops': 132,
'Processor': 128
}, {
'date': '2017-10-31T18:30:00.000Z',
'Ram': 844,
'Laptops': 287,
'Processor': 106
}, {
'date': '2017-11-30T18:30:00.000Z',
'Ram': 1725,
'Laptops': 114,
'Processor': 131
}, {
'date': '2017-12-31T18:30:00.000Z',
'Ram': 2761,
'Laptops': 83,
'Processor': 324
},
{
'date': '2018-01-31T18:30:00.000Z',
'Ram': 2120,
'Laptops': 42,
'Processor': 361
}, {
'date': '2018-02-28T18:30:00.000Z',
'Ram': 1205,
'Laptops': 32,
'Processor': 172
}, {
'date': '2018-03-31T18:30:00.000Z',
'Ram': 477,
'Laptops': 48,
'Processor': 57
}, {
'date': '2018-04-30T18:30:00.000Z',
'Ram': 508,
'Laptops': 49,
'Processor': 37
}
];
salesData.forEach(function(d) {
d = type(d);
});
var layers = d3.stack()
.keys(group)
.offset(d3.stackOffsetDiverging)
(salesData);
var svg = d3.select("svg"),
margin = {
top: 20,
right: 30,
bottom: 60,
left: 60
},
width = +svg.attr("width"),
height = +svg.attr("height");
var x = d3.scaleLinear()
.rangeRound([margin.left, width - margin.right]);
x.domain([d3.min(layers, stackMin), d3.max(layers, stackMax)]);
var y = d3.scaleBand()
.rangeRound([height - margin.bottom, margin.top])
.padding(0.1);
y.domain(salesData.map(function(d) {
return d.date;
}))
function stackMin(layers) {
return d3.min(layers, function(d) {
return d[0];
});
}
function stackMax(layers) {
return d3.max(layers, function(d) {
return d[1];
});
}
var z = d3.scaleOrdinal(d3.schemeCategory10);
var maing = svg.append("g")
.selectAll("g")
.data(layers);
var g = maing.enter().append("g")
.attr("fill", function(d) {
return z(d.key);
});
var rect = g.selectAll("rect")
.data(function(d) {
d.forEach(function(d1) {
d1.key = d.key;
return d1;
});
return d;
})
.enter().append("rect")
.attr("data", function(d) {
var data = {};
data["key"] = d.key;
data["value"] = d.data[d.key];
var total = 0;
group.map(function(d1) {
total = total + d.data[d1]
});
data["total"] = total;
return JSON.stringify(data);
})
.attr("width", function(d) {
return x(d[1]) - x(d[0]);
})
.attr("x", function(d) {
return x(d[0]);
})
.attr("y", function(d) {
return y(d.data.date);
})
.attr("height", y.bandwidth);
rect.on("mouseover", function() {
var currentEl = d3.select(this);
var fadeInSpeed = 120;
d3.select("#recttooltip_" + mainDivName)
.transition()
.duration(fadeInSpeed)
.style("opacity", function() {
return 1;
});
d3.select("#recttooltip_" + mainDivName).attr("transform", function(d) {
var mouseCoords = d3.mouse(this.parentNode);
var xCo = 0;
if (mouseCoords[0] + 10 >= width * 0.80) {
xCo = mouseCoords[0] - parseFloat(d3.selectAll("#recttooltipRect_" + mainDivName)
.attr("width"));
} else {
xCo = mouseCoords[0] + 10;
}
var x = xCo;
var yCo = 0;
if (mouseCoords[0] + 10 >= width * 0.80) {
yCo = mouseCoords[1] + 10;
} else {
yCo = mouseCoords[1];
}
var x = xCo;
var y = yCo;
return "translate(" + x + "," + y + ")";
});
//CBT:calculate tooltips text
var tooltipData = JSON.parse(currentEl.attr("data"));
var tooltipsText = "";
d3.selectAll("#recttooltipText_" + mainDivName).text("");
var yPos = 0;
d3.selectAll("#recttooltipText_" + mainDivName).append("tspan").attr("x", 0).attr("y", yPos * 10).attr("dy", "1.9em").text(tooltipData.key + ": " + tooltipData.value);
yPos = yPos + 1;
d3.selectAll("#recttooltipText_" + mainDivName).append("tspan").attr("x", 0).attr("y", yPos * 10).attr("dy", "1.9em").text("Total" + ": " + tooltipData.total);
//CBT:calculate width of the text based on characters
var dims = helpers.getDimensions("recttooltipText_" + mainDivName);
d3.selectAll("#recttooltipText_" + mainDivName + " tspan")
.attr("x", dims.w + 4);
d3.selectAll("#recttooltipRect_" + mainDivName)
.attr("width", dims.w + 10)
.attr("height", dims.h + 20);
});
rect.on("mousemove", function() {
var currentEl = d3.select(this);
currentEl.attr("r", 7);
d3.selectAll("#recttooltip_" + mainDivName)
.attr("transform", function(d) {
var mouseCoords = d3.mouse(this.parentNode);
var xCo = 0;
if (mouseCoords[0] + 10 >= width * 0.80) {
xCo = mouseCoords[0] - parseFloat(d3.selectAll("#recttooltipRect_" + mainDivName)
.attr("width"));
} else {
xCo = mouseCoords[0] + 10;
}
var x = xCo;
var yCo = 0;
if (mouseCoords[0] + 10 >= width * 0.80) {
yCo = mouseCoords[1] + 10;
} else {
yCo = mouseCoords[1];
}
var x = xCo;
var y = yCo;
return "translate(" + x + "," + y + ")";
});
});
rect.on("mouseout", function() {
var currentEl = d3.select(this);
d3.select("#recttooltip_" + mainDivName)
.style("opacity", function() {
return 0;
})
.attr("transform", function(d, i) {
// klutzy, but it accounts for tooltip padding which could push it onscreen
var x = -500;
var y = -500;
return "translate(" + x + "," + y + ")";
});
});
svg.append("g")
.attr("transform", "translate(0," + (height - margin.bottom) + ")")
.call(d3.axisBottom(x))
.append("text")
.attr("x", width / 2)
.attr("y", margin.bottom * 0.5)
.attr("dx", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "start")
.text("Sales");
var ele = svg.append("g")
.attr("transform", "translate(" + margin.left + ",0)")
.call(d3.axisLeft(y));
ele.selectAll("text")
.attr("transform", "rotate(-55)")
.attr("dx", ".5em")
.attr("dy", "-.9em");
ele.append("text")
.attr("transform", "rotate(-90)")
.attr("x", 0 - (height / 2))
.attr("y", 15 - (margin.left))
.attr("dy", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "middle")
.text("Month");
var rectTooltipg = svg.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("text-anchor", "end")
.attr("id", "recttooltip_" + mainDivName)
.attr("style", "opacity:0")
.attr("transform", "translate(-500,-500)");
rectTooltipg.append("rect")
.attr("id", "recttooltipRect_" + mainDivName)
.attr("x", 0)
.attr("width", 120)
.attr("height", 80)
.attr("opacity", 0.71)
.style("fill", "#000000");
rectTooltipg
.append("text")
.attr("id", "recttooltipText_" + mainDivName)
.attr("x", 30)
.attr("y", 15)
.attr("fill", function() {
return "#fff"
})
.style("font-size", function(d) {
return 10;
})
.style("font-family", function(d) {
return "arial";
})
.text(function(d, i) {
return "";
});
function type(d) {
d.date = parseDate(new Date(d.date));
group.forEach(function(c) {
d[c] = +d[c];
});
return d;
}
var helpers = {
getDimensions: function(id) {
var el = document.getElementById(id);
var w = 0,
h = 0;
if (el) {
var dimensions = el.getBBox();
w = dimensions.width;
h = dimensions.height;
} else {
console.log("error: getDimensions() " + id + " not found.");
}
return {
w: w,
h: h
};
}
};
</script>
Modified http://code.jquery.com/jquery-latest.min.js to a secure url
https://code.jquery.com/jquery-latest.min.js
https://d3js.org/d3.v4.min.js