xxxxxxxxxx
<html>
<head>
</head>
<body>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="chart" width="800" height="500" style="width: 800;height: 500">
<svg width="800" height="500" class="chartSvg"></svg>
<a
href="https://stackoverflow.com/users/7430694/chandrakant-thakkar"
style="position: absolute;top: 87%;left: 77%;"
target="_blank"
>
<img
src="https://stackoverflow.com/users/flair/7430694.png"
width="208"
height="58"
alt="profile for Chandrakant Thakkar at Stack Overflow, Q&A for professional and enthusiast programmers"
title="profile for Chandrakant Thakkar at Stack Overflow, Q&A for professional and enthusiast programmers"
/>
</a>
</div>
<script>
var groupChartData = [
// { "Team A": 0, "Team B": 0, over: 0 },
{ "Team A": 8, "Team B": 15, over: 1 },
{ "Team A": 15, "Team B": 17, over: 2 },
{ "Team A": 19, "Team B": 22, over: 3 },
{ "Team A": 38, "Team B": 30, over: 4 },
{ "Team A": 41, "Team B": 37, over: 5 },
{ "Team A": 47, "Team B": 38, over: 6 },
{ "Team A": 54, "Team B": 44, over: 7 },
{ "Team A": 67, "Team B": 46, over: 8 },
{ "Team A": 68, "Team B": 54, over: 9 },
{ "Team A": 76, "Team B": 63, over: 10 },
{ "Team A": 80, "Team B": 71, over: 11 },
{ "Team A": 80, "Team B": 91, over: 12 },
{ "Team A": 88, "Team B": 94, over: 13 },
{ "Team A": 93, "Team B": 103, over: 14 },
{ "Team A": 100, "Team B": 108, over: 15 },
{ "Team A": 109, "Team B": 122, over: 16 },
{ "Team A": 126, "Team B": 137, over: 17 },
{ "Team A": 147, "Team B": 147, over: 18 },
{ "Team A": 157, "Team B": 150, over: 19 },
{ "Team A": null, "Team B": 155, over: 20 }
];
var columnsInfo = { "Team A": "Team A", "Team B": "Team B" };
const width = 800;
const height = 500;
const margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
};
const xAxisField = "over";
const group1Field = "Team A";
const group2Field = "Team B";
const wordWrap = true;
const group1MinMax = d3.extent(groupChartData.map(d => d[group1Field]));
const group2MinMax = d3.extent(groupChartData.map(d => d[group2Field]));
const xAxisScale = d3
.scaleLinear()
.domain([d3.min([...group1MinMax, ...group2MinMax]), d3.max([...group1MinMax, ...group2MinMax])])
.range([0, width - (margin.left + margin.right)]);
const yAxisScale = d3
.scaleLinear()
.domain([d3.min(groupChartData.map(d => d[xAxisField])), d3.max(groupChartData.map(d => d[xAxisField]))])
.range([height - (margin.top + margin.bottom), 0]);
const mainG = d3
.select(".chartSvg")
.append("g")
.attr("transform", `translate(0,0)`);
const xAxisG = mainG
.append("g")
.attr(
"transform",
`translate(${margin.left},${height - margin.bottom})`
).call(d3.axisBottom(xAxisScale))
.append("text")
// .attr("transform", "rotate(-90)")
.attr("y", margin.bottom*0.9)
.attr("x", (width - (margin.left + margin.right)) / 2)
.style("fill", "#C4C4C4")
.style("font-weight", "bold")
.style("font-size", "14px")
.text("Runs");
const yAxisG = mainG
.append("g")
.classed("yAxisG", true)
.attr("transform", `translate(${margin.left},${margin.top})`);
//CBT:draw y Axis start
yAxisG
.call(d3.axisLeft(yAxisScale))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", -margin.left * 0.5)
.attr("x", -(height - (margin.top + margin.bottom)) / 2)
.style("fill", "#C4C4C4")
.style("font-weight", "bold")
.style("font-size", "14px")
.text("Overs");
//CBT:draw y Axis end
var line = d3
.line()
.x(function(d) {
return xAxisScale(d.x);
})
.y(function(d) {
return yAxisScale(d.y);
});
// define the area
var area = d3.area()
.x(function(d) { return xAxisScale(d.x); })
.y0(0)
.y1(function(d) { return yAxisScale(d.y); });
//CBT:Draw first line start
const group1Line = mainG
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`)
.append("g")
.classed("group1-line", true);
group1Line
.append("path")
.data([
groupChartData
.filter(function(d, i) {
//CBT:remove last blank or value is 0 data to show only that much of line
if (
(d[group1Field] != null && d[group1Field] != undefined) ||
i == 0
)
return d;
})
.map(d => {
return { x: d[group1Field], y:d[xAxisField] };
})
])
.attr("d",line)
.style("stroke", function(d) {
return "#2a98cd";
})
.style("fill", "none")
.style("stroke-width", "3px");
group1Line
.append("path")
.data([
groupChartData
.filter(function(d, i) {
//CBT:remove last blank or value is 0 data to show only that much of line
if (
(d[group1Field] != null && d[group1Field] != undefined) ||
i == 0
)
return d;
})
.map(d => {
return { x: d[group1Field], y: d[xAxisField] };
})
])
.attr("d",area)
.style("fill-opacity", "0.3")
.style("fill", "#2a98cd");
//CBT:Draw first line end
//CBT:Draw second line start
const group2Line = mainG
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`)
.append("g")
.classed("group2-line", true);
group2Line
.append("path")
.data([
groupChartData
.filter(function(d, i) {
//CBT:remove last blank or value is 0 data to show only that much of line
if ((d[group2Field] != null && d[group2Field] != undefined) || i == 0)
return d;
})
.map(d => {
return { x:d[group2Field] , y: d[xAxisField] };
})
])
.attr("d", line)
.style("stroke", function(d) {
return "#df7247";
})
.style("fill", "none")
.style("stroke-width", "3px");
group2Line
.append("path")
.data([
groupChartData
.filter(function(d, i) {
//CBT:remove last blank or value is 0 data to show only that much of line
if ((d[group2Field] != null && d[group2Field] != undefined) || i == 0)
return d;
})
.map(d => {
return { x: d[group2Field], y: d[xAxisField] };
})
])
.attr("d", area)
.style("fill", "#df7247")
.style("fill-opacity", "0.3");
//CBT:Draw second line end
const circleRadius = 4;
const tooltip = mainG
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
var mouseOverG = mainG
.append("g")
.attr("class", "mouseOverEffect")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const moveOnMouseOverG = mouseOverG
.append("g")
.attr("transform", "translate(0,0)");
const groupLine = moveOnMouseOverG
.append("path")
.attr("d", `M0 0 L${width - (margin.top + margin.left)} 0 Z`)
.attr("class", "mouse-line")
.style("stroke", "black")
.style("stroke-opacity", "0")
.style("stroke-width", "2px");
const group1Circle = moveOnMouseOverG
.append("circle")
.attr("r", circleRadius)
.style("fill", "transparent")
.style("stroke", "green")
.style("stroke-width", "2px")
.style("stroke-opacity", "0");
const group2Circle = moveOnMouseOverG
.append("circle")
.attr("r", circleRadius)
.style("fill", "transparent")
.style("stroke", "green")
.style("stroke-width", "2px")
.style("stroke-opacity", "0");
//CBT:tooltip start
var tooltipG = tooltip
.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("style", "opacity:0")
.attr("transform", `translate(0,0)`);
const rectTooltip = tooltipG.append("rect").style("fill", "#ccc");
const textTooltip = tooltipG.append("text").text("");
//CBT:tooltip end
mouseOverG
.append("svg:rect")
.data([groupChartData])
.attr("width", width - (margin.left + margin.right))
.attr("height", height - (margin.top + margin.bottom))
.attr("fill", "none")
.attr("pointer-events", "all")
.on("mouseenter", function(data) {
group1Circle.style("stroke-opacity", 1);
group2Circle.style("stroke-opacity", 1);
groupLine.style("stroke-opacity", 1);
tooltipG.style("opacity", 1);
})
.on("mouseout", function(data) {
group1Circle.style("stroke-opacity", 0);
group2Circle.style("stroke-opacity", 0);
groupLine.style("stroke-opacity", 0);
tooltipG.style("opacity", 0);
})
.on("mousemove", function(data) {
var mouse = d3.mouse(this);
console.log(
"Y",
mouse[1],
"yValue:",
Math.round(yAxisScale.invert(mouse[1]))
);
moveOnMouseOverG.attr(
"transform",
`translate(0,${yAxisScale(
Math.round(yAxisScale.invert(mouse[1]))
)})`
);
let tooltipXPosition =
yAxisScale(Math.round(yAxisScale.invert(mouse[1]))) + 10;
const filteredData = data.filter(
d => d[xAxisField] == Math.round(yAxisScale.invert(mouse[1]))
);
textTooltip.text("Over:" + filteredData[0][xAxisField]);
const heightOfText = textTooltip.node().getBBox().height;
const widthOfText = textTooltip.node().getBBox().width;
textTooltip.text("");
textTooltip
.append("tspan")
.attr("y", heightOfText + 10)
.attr("x", 10)
.text("Over: " + filteredData[0][xAxisField]);
textTooltip
.append("tspan")
.attr("y", heightOfText * 2 + 15)
.attr("x", 10)
.text(group1Field + ": " + filteredData[0][group1Field]);
textTooltip
.append("tspan")
.attr("y", heightOfText * 3 + 20)
.attr("x", 10)
.text(group2Field + ": " + filteredData[0][group2Field]);
rectTooltip.attr("height", textTooltip.node().getBBox().height + 20);
rectTooltip.attr("width", textTooltip.node().getBBox().width + 20);
if (
textTooltip.node().getBBox().height + 20 + tooltipXPosition >
height - (margin.top + margin.bottom)
) {
tooltipXPosition =
tooltipXPosition - 20 - (textTooltip.node().getBBox().height + 20);
}
tooltipG.attr("transform", `translate(${width-(margin.right+margin.left+textTooltip.node().getBBox().width)},${tooltipXPosition})`);
if (filteredData.length > 0 && filteredData[0][group1Field] != null) {
group1Circle.style("stroke-opacity", 1);
group1Circle.style("cx", xAxisScale(filteredData[0][group1Field]));
} else {
group1Circle.style("stroke-opacity", 0);
}
if (filteredData.length > 0 && filteredData[0][group2Field] != null) {
group2Circle.style("stroke-opacity", 1);
group2Circle.style("cx", xAxisScale(filteredData[0][group2Field]));
} else {
group2Circle.style("stroke-opacity", 0);
}
});
//CBT:Legend Start
$("#chart").before(
"<div id='Legend_chart' class='pmd-card-body' style='margin-top:0; margin-bottom:0;'></div>"
);
var keys = [
{
color: "#2a98cd",
label: group1Field
},
{
color: "#df7247",
label: group2Field
}
];
keys.forEach(function(d) {
var cloloCode = d.color;
$("#Legend_chart").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.label +
" </span>\
</span>"
);
});
//CBT:Legend End
</script>
</body>
</html>
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