我已经创建了一个带有工具提示的堆叠式条形图,但是当从下拉按钮中选择一个新值时,数据不会重新呈现,而是建立在相同的前一个条形图上。如何以这样的方式修改图表:当选定的图表中的新下拉值随过渡(动画)而变化时。
<!DOCTYPE html>
<meta charset="utf-8">
<head>
</head>
<body>
<select id="queryYear" data-toggle="modal" data-target="#myModal" class="btn btn-danger ">
<option value="2019" selected="selected">2019</option>
<option value="2018">2018</option>
<option value="2017">2017</option>
</select>
<div id="charts" style="margin-left:45px;margin-top:20px">
<h3>Payee Remmittance</h3>
<svg width="1000" 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 = ["Not Paid", "Paid"];
var parseDate = d3.timeFormat("%b-%Y");
var mainDiv = "#charts";
var mainDivName = "charts";
createChartLegend(mainDiv, group);
var salesData = [{
'agency': 'Manufacturing',
'Paid': 35,
'Not Paid': 10
}, {
'agency': 'CONSTRUCTION ',
'Paid': 82,
'Not Paid': 1
},
{
'agency': 'INSURANCE',
'Paid': 7,
'Not Paid': 81
}, {
'agency': 'OIL & GAS',
'Paid': 50,
'Not Paid': 13
}, {
'agency': 'TRANSPORT',
'Paid': 19,
'Not Paid': 28
}, {
'agency': 'HEALTH CARE ',
'Paid': 17,
'Not Paid': 23
}, {
'agency': 'LEGAL SERVICES',
'Paid': 27,
'Not Paid': 8
},
{
'agency': 'INFORMATION & COMMUNICATION TECH ',
'Paid': 21,
'Not Paid': 2
}, {
'agency': 'TELECOMMUNICATION',
'Paid': 12,
'Not Paid': 32
}, {
'agency': 'EDUCATIONAL SERVICES ',
'Paid': 47,
'Not Paid': 48
}
];
var salesData1 = [{
'agency': 'Manufacturing',
'Paid': 125,
'Not Paid': 200
}, {
'agency': 'CONSTRUCTION ',
'Paid': 182,
'Not Paid': 11
},
{
'agency': 'INSURANCE',
'Paid': 171,
'Not Paid': 181
}, {
'agency': 'OIL & GAS',
'Paid': 150,
'Not Paid': 113
}, {
'agency': 'TRANSPORT',
'Paid': 119,
'Not Paid': 128
}, {
'agency': 'HEALTH CARE ',
'Paid': 117,
'Not Paid': 123
}, {
'agency': 'LEGAL SERVICES',
'Paid': 127,
'Not Paid': 18
},
{
'agency': 'INFORMATION & COMMUNICATION TECH ',
'Paid': 121,
'Not Paid': 12
}, {
'agency': 'TELECOMMUNICATION',
'Paid': 112,
'Not Paid': 32
}, {
'agency': 'EDUCATIONAL SERVICES ',
'Paid': 147,
'Not Paid': 48
}
];
d3.select("#queryYear").on("change", function(d) {
var v = d3.select(this).property('value');
console.log(v)
if (v == 2018) {
console.log(salesData1)
update(salesData1)
}
if (v == 2017) {
console.log(salesData)
update(salesData)
}
if (v == 2019) {
update(salesData)
}
})
function update(mda){
mda.forEach(function(d) {
d = type(d);
});
var layers = d3.stack()
.keys(group)
.offset(d3.stackOffsetDiverging)
(mda)
;
var svg = d3.select("svg"),
margin = {
top: 20,
right: 30,
bottom: 60,
left: 120
},
width = +svg.attr("width"),
height = +svg.attr("height");
var t = d3.transition()
.duration(4000);
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(mda.map(function(d) {
return d.agency;
}))
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)
.remove();
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.agency);
})
.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("Count")
.remove()
.exit();
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("Agency Name");
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.agency = d.agency;
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>