我试图用d3.js可视化交互式折线图。我从JSON文件(dashboard.json)获取数据。我已经有了一个交互式条形图,它通过悬停在小条线上显示一个饼图。我试图在条形图中添加折线图。因此,最终悬停在条形图上必须同时显示饼图和折线图。
This is a picture of how it looks like now
这是我的代码(有些东西是荷兰语):
//barchart
var valueWeek= 36;
var margin = {top: 5, right: 100, bottom: 90, left: 39};
var height = 405;
var barWidth = 50;
var input = document.getElementsByTagName('input')[0];
var output = document.getElementsByTagName('output')[0];
var width = 350;
var y = d3.scale.linear().range([height, 0]);
var x = d3.scale.ordinal().rangeRoundBands([0, width], 0);
//piechart
var withdPie = 1000;
var heightPie = 1000;
var radiusPie = 160;
var kleur = d3.scale.ordinal().range(["#b8d622", "#8523db", "#207cca","#3d1cb2", "#638e00", "#00a000"]);
d3.json('dashboard.json', draw);
function draw(error, data) {
if (error) throw error;
// buttons
d3.select('#week36')
.on('click', function(){
week36(); });
function week36(){
valueWeek = 36;
console.log(valueWeek);
d3.selectAll(".PieChartBlock").remove(); // RESET PIECHART
d3.selectAll("rect").remove(); // RESET BARCHART
updateBarChart();
}
d3.select('#week37')
.on('click', function(){
week37(); });
function week37(){
valueWeek = 37;
console.log(valueWeek);
d3.selectAll(".PieChartBlock").remove(); // RESET PIECHART
d3.selectAll("rect").remove(); // RESET BARCHART
updateBarChart();
}
d3.select('#week38')
.on('click', function(){
week38(); });
function week38(){
valueWeek = 38;
console.log(valueWeek);
d3.selectAll(".PieChartBlock").remove(); // RESET PIECHART
d3.selectAll("rect").remove(); // RESET BARCHART
updateBarChart();
}
d3.select('#week39')
.on('click', function(){
week39();});
function week39(){
valueWeek = 39;
console.log(valueWeek);
d3.selectAll(".PieChartBlock").remove(); // RESET PIECHART
d3.selectAll("rect").remove(); // RESET BARCHART
updateBarChart();
}
d3.select('#week40')
.on('click', function(){
week40();});
function week40(){
valueWeek = 40;
console.log(valueWeek);
d3.selectAll(".PieChartBlock").remove(); // RESET PIECHART
d3.selectAll("rect").remove(); // RESET BARCHART
updateBarChart();
}
d3.select('#week41')
.on('click', function(){
week41();});
function week41(){
valueWeek = 41;
console.log(valueWeek);
d3.selectAll(".PieChartBlock").remove(); // RESET PIECHART
d3.selectAll("rect").remove(); // RESET BARCHART
updateBarChart();
}
//barchart
var EmotieBarchart = d3.select('#EmotieBarchart')
.append('svg')
.attr('class', 'chart')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
x.domain(data.map(function (d) { return d.dag; }));
y.domain([0, 10]);
//Y-as
EmotieBarchart
.append('g')
.attr('class', 'y axis')
.call(d3.svg.axis().scale(y).orient('left'));
//X-as
EmotieBarchart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.svg.axis().scale(x).orient('bottom'))
.selectAll("text")
.attr("transform", "rotate(40)")
.attr("dx", "3em")
.attr("dy", "1em");
updateBarChart();
input.addEventListener('input', function () {
d3.selectAll(".PieChartBlock").remove(); // RESET PIECHART
output.value = input.value;
console.log(" slider update")
updateBarChart();
});
//update barchart
function updateBarChart() {
var min = Number(input.value);
var selectedWeek = valueWeek;
var subset = data.filter(function (d) {
return d.gemoed >= min && d.week == selectedWeek;
});
var bars = EmotieBarchart.selectAll('.barLine').data(subset);
bars
.enter()
.append('g')
.attr("class", "barLine");
bars
.exit()
.remove();
// Needed to remove all rects before adding one
d3.selectAll('.barLine rect').remove();
d3.selectAll('.barLine text').remove();
bars.append('rect')
.attr('width', barWidth - 3)
.attr('x', function (d, i) { return i * barWidth })
.attr('y', function (d) { return y(d.gemoed); })
.attr('height', function (d) { return height - y(d.gemoed); })
.attr('gemoed', function (d) { return d.gemoed })
.attr('date', function (d) { return d.datum })
.attr('day', function (d) { return d.dag })
.attr('number', function (d) { return d.ID })
.on("mouseover", barMouseOver)
;
}
// UPDATE PIEBARCHART
function updatePieChart() {
// PIE CHART
var feest = data[selected].feest;
var boek = data[selected].boek;
var reizen = data[selected].reizen;
var tv = data[selected].tv;
var huishouden = data[selected].huishouden;
var school = data[selected].school;
var dag = data[selected].dag;
var datum = data[selected].datum;
var week = data[selected].week;
//tooltip//
var tooltip = d3.select("body")
.append("div")
.style("max-width", "70px")
.style("padding", "1em")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.style("background", "white");
//waardes van de piechart
dataPie = [{"label":"TV", "value":tv},
{"label":"Huishouden", "value":huishouden},
{"label":"Reizen", "value":reizen},
{"label":"school", "value":school},
{"label":"boek", "value":boek},
{"label":"feest", "value":feest}];
//piechart visualisatie
var visualchart = d3.select("#DagelijkseActiviteiten")
.append("svg")
.data([dataPie])
.attr("width", withdPie)
.attr("height", heightPie)
.attr("class", "PieChartBlock")
.append("g")
.attr("transform", "translate(" + radiusPie*1.5 + "," + radiusPie*1.5 + ")");
// Tekst boven de piechart
d3.select("#DagelijkseActiviteiten svg")
.append('text')
.attr("text-anchor", 'middle')
.attr("x", "13.5em")
.attr("y", "2em")
.attr("dy", ".75em")
.text(function(d) {
return 'Dagelijkse activiteiten op ' + dag + ' ' + datum + ' in Week: '+ week;
});
var arc = d3.svg.arc()
.outerRadius(radiusPie); // Radius
var pie = d3.layout.pie()
.value(function(d) { return d.value; }); // Gets value's of school, huishouden and tv
var arcs = visualchart.selectAll("g.slice") //this selects all <g> elements with class slice (there aren't any yet)
.data(pie) //associate the generated pie data (an array of arcs, each having startAngle, endAngle and value properties)
.enter() //this will create <g> elements for every "extra" data element that should be associated with a selection. The result is creating a <g> for every object in the data array
.append("g") //create a group to hold each slice (we will have a <path> and a <text> element associated with each slice)
.attr("class", "slice") //allow us to style things in the slices (like text)
.on("mouseover", function(d){tooltip.text(tv + " uur TV" +' '+ boek + " uur boek"+' '+ school + " uur school"+' '+ reizen + " uur reizen"+' '+ feest + " uur feest"+' '+ huishouden + " uur huishouden"); return tooltip.style("visibility", "visible");})
.on("mousemove", function(){return tooltip.style("top", (d3.event.pageY-100)+"px").style("left",(d3.event.pageX-25)+"px");})
.on("mouseout", function(){return tooltip.style("visibility", "hidden");
});
arcs
.append("path")
.attr("fill", function(d, i) { return kleur(i); } )
.attr("d", arc);
arcs
.append("text")
.attr("transform", function(d) {
d.innerRadius = 10;
d.outerRadius = radiusPie;
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle")
.attr('class', 'labelText')
.attr("value", function(d, i) { return dataPie[i].value; })
.text(function(d, i) {
if (dataPie[i].value > 0) { // Checks if value is 0, then is not visible
return dataPie[i].label;
}
});
}
// Show PieChart that belongs to the bar
function barMouseOver() {
d3.selectAll(".PieChartBlock").remove();
selected = d3.select(this).attr("number");
updatePieChart();
}
}
这是我的dashboard.json文件的简短示例:
[
{
"ID": 0,
"datum": "05-09-2016",
"week": 36,
"dag": "maandag",
"gemoed": 5,
"school": 3.20,
"huishouden": 0,
"tv": 0,
"reizen": 2.5,
"feest": 0,
"boek": 1
},
{
"ID": 1,
"datum": "06-09-2016",
"week": 36,
"dag": "dinsdag",
"gemoed": 6,
"school": 0,
"huishouden": 1,
"tv": 1,
"reizen": 0,
"feest": 0,
"boek": 1
},
{
"ID": 2,
"datum": "07-09-2016",
"week": 36,
"dag": "woensdag",
"gemoed": 6,
"school": 3.50,
"huishouden": 0,
"tv": 1,
"reizen": 3,
"feest": 0,
"boek": 1
},
{
"ID": 3,
"datum": "08-09-2016",
"week": 36,
"dag": "donderdag",
"gemoed": 5,
"school": 6.40,
"huishouden": 0,
"tv": 0,
"reizen": 2.10,
"feest": 0,
"boek": 1
},
{
"ID": 4,
"datum": "09-09-2016",
"week": 36,
"dag": "vrijdag",
"gemoed": 7,
"school": 0,
"huishouden": 1,
"tv": 4,
"reizen": 0,
"feest": 0,
"boek": 1
},
{
"ID": 5,
"datum": "10-09-2016",
"week": 36,
"dag": "zaterdag",
"gemoed": 9,
"school": 0,
"huishouden": 0,
"tv": 0,
"reizen": 0,
"feest": 12,
"boek": 0
},
{
"ID": 6,
"datum": "11-09-2016",
"week": 36,
"dag": "zondag",
"gemoed": 7,
"school": 0,
"huishouden": 0,
"tv": 4,
"reizen": 0,
"feest": 0,
"boek": 1
}]