D3.js - ตัวอย่างการทำงาน
ให้เราแสดงแผนภูมิแท่งแบบเคลื่อนไหวในบทนี้ สำหรับตัวอย่างนี้เรานำไฟล์ data.csv ที่ใช้ในบทก่อนหน้าของเรกคอร์ดประชากรเป็นชุดข้อมูลและสร้างแผนภูมิแท่งแบบเคลื่อนไหว
ในการดำเนินการนี้เราต้องทำตามขั้นตอนต่อไปนี้ -
Step 1 - Apply styles - ใช้สไตล์ CSS โดยใช้การเข้ารหัสที่ระบุด้านล่าง
<style>
.bar {
fill: green;
}
.highlight {
fill: red;
}
.title {
fill: blue;
font-weight: bold;
}
</style>
Step 2 - Define variables - ให้เรากำหนดแอตทริบิวต์ SVG โดยใช้สคริปต์ด้านล่าง
<script>
var svg = d3.select("svg"), margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin;
</script>
Step 3 - Append text - ตอนนี้ต่อท้ายข้อความและใช้การเปลี่ยนแปลงโดยใช้การเข้ารหัสด้านล่าง
svg.append("text")
.attr("transform", "translate(100,0)")
.attr("x", 50)
.attr("y", 50)
.attr("font-size", "20px")
.attr("class", "title")
.text("Population bar chart")
Step 4 - Create scale range- ในขั้นตอนนี้เราสามารถสร้างช่วงสเกลและต่อท้ายองค์ประกอบของกลุ่มได้ มีการกำหนดไว้ด้านล่าง
var x = d3.scaleBand().range([0, width]).padding(0.4),
y = d3.scaleLinear()
.range([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + 100 + "," + 100 + ")");
Step 5 - Read data - เราได้สร้างไฟล์ data.csvไฟล์ในตัวอย่างก่อนหน้าของเรา ไฟล์เดียวกันเราได้ใช้ที่นี่
year,population
2006,40
2008,45
2010,48
2012,51
2014,53
2016,57
2017,62
ตอนนี้อ่านไฟล์ด้านบนโดยใช้รหัสด้านล่าง
d3.csv("data.csv", function(error, data) {
if (error) {
throw error;
}
Step 6 - Set domain - ตอนนี้ตั้งค่าโดเมนโดยใช้การเข้ารหัสด้านล่าง
x.domain(data.map(function(d) { return d.year; }));
y.domain([0, d3.max(data, function(d) { return d.population; })]);
Step 7 - Add X-axis- ตอนนี้คุณสามารถเพิ่มแกน X ในการเปลี่ยนแปลงได้ ดังแสดงด้านล่าง
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)).append("text")
.attr("y", height - 250).attr("x", width - 100)
.attr("text-anchor", "end").attr("font-size", "18px")
.attr("stroke", "blue").text("year");
Step 8 - Add Y-axis - เพิ่มแกน Y ในการแปลงโดยใช้รหัสที่ระบุด้านล่าง
g.append("g")
.append("text").attr("transform", "rotate(-90)")
.attr("y", 6).attr("dy", "-5.1em")
.attr("text-anchor", "end").attr("font-size", "18px")
.attr("stroke", "blue").text("population");
Step 9 - Append group elements - ตอนนี้ต่อท้ายองค์ประกอบของกลุ่มและใช้การแปลงกับแกน Y ตามที่กำหนดไว้ด้านล่าง
g.append("g")
.attr("transform", "translate(0, 0)")
.call(d3.axisLeft(y))
Step 10 - Select the bar class - ตอนนี้เลือกองค์ประกอบทั้งหมดในคลาสบาร์ตามที่กำหนดไว้ด้านล่าง
g.selectAll(".bar")
.data(data).enter()
.append("rect")
.attr("class", "bar")
.on("mouseover", onMouseOver)
.on("mouseout", onMouseOut)
.attr("x", function(d) { return x(d.year); })
.attr("y", function(d) { return y(d.population); })
.attr("width", x.bandwidth())
.transition()
.ease(d3.easeLinear)
.duration(200)
.delay(function (d, i) {
return i * 25;
})
.attr("height", function(d) { return height - y(d.population); });
});
ที่นี่เราได้เพิ่มเหตุการณ์ Listener สำหรับ mouseout และ mouseover เพื่อแสดงภาพเคลื่อนไหว มันใช้ภาพเคลื่อนไหวเมื่อเมาส์เลื่อนไปที่แถบใดแถบหนึ่งและออกไปจากแถบนั้น ฟังก์ชันเหล่านี้จะอธิบายในขั้นตอนต่อไปนี้
.ease(d3.easeLinear)ฟังก์ชันนี้ใช้เพื่อทำการเคลื่อนไหวที่ชัดเจนในแอนิเมชั่น มันประมวลผลการเคลื่อนไหวช้าเข้าและออกช้าด้วยระยะเวลา 200 ความล่าช้าสามารถคำนวณได้โดยใช้ -
.delay(function (d, i) {
return i * 25;
})
Step 11 - Mouseover event handler function - ให้เราสร้างตัวจัดการเหตุการณ์เมาส์โอเวอร์เพื่อจัดการเหตุการณ์เมาส์ดังที่แสดงด้านล่าง
function onMouseOver(d, i) {
d3.select(this)
.attr('class', 'highlight');
d3.select(this)
.transition()
.duration(200)
.attr('width', x.bandwidth() + 5)
.attr("y", function(d) { return y(d.population) - 10; })
.attr("height", function(d) { return height - y(d.population) + 10; });
g.append("text")
.attr('class', 'val')
.attr('x', function() {
return x(d.year);
})
.attr('y', function() {
return y(d.value) - 10;
})
}
ในกรณีการวางเมาส์เราต้องการเพิ่มความกว้างและความสูงของแถบและสีของแถบที่เลือกเป็นสีแดง สำหรับสีเราได้เพิ่มคลาส 'ไฮไลต์' ซึ่งจะเปลี่ยนสีของแถบที่เลือกเป็นสีแดง
ฟังก์ชันการเปลี่ยนไปยังแถบเป็นระยะเวลา 200 มิลลิวินาที เมื่อเราเพิ่มความกว้างของแท่งขึ้น 5px และความสูง 10px การเปลี่ยนจากความกว้างและความสูงก่อนหน้าของแท่งไปเป็นความกว้างและความสูงใหม่จะเป็นระยะเวลา 200 มิลลิวินาที
จากนั้นเราจะคำนวณค่า 'y' ใหม่ให้กับแถบเพื่อไม่ให้แถบบิดเบือนเนื่องจากค่าความสูงใหม่
Step 12 - Mouseout event handler function- ให้เราสร้างตัวจัดการเหตุการณ์ mouseout เพื่อจัดการเหตุการณ์เมาส์ มีการกำหนดไว้ด้านล่าง
function onMouseOut(d, i) {
d3.select(this).attr('class', 'bar');
d3.select(this)
.transition()
.duration(400).attr('width', x.bandwidth())
.attr("y", function(d) { return y(d.population); })
.attr("height", function(d) { return height - y(d.population); });
d3.selectAll('.val')
.remove()
}
ที่นี่ในเหตุการณ์ mouseout เราต้องการลบคุณสมบัติการเลือกที่เราใช้ในเหตุการณ์ mouseover ดังนั้นเราจึงเปลี่ยนคลาสบาร์กลับเป็นคลาส 'บาร์' เดิมและคืนค่าความกว้างและความสูงดั้งเดิมของแถบที่เลือกและคืนค่า y กลับเป็นค่าเดิม
d3.selectAll(‘.val’).remove() ฟังก์ชันใช้เพื่อลบค่าข้อความที่เราได้เพิ่มในระหว่างการเลือกแถบ
Step 13 - Working Example- โปรแกรมที่สมบูรณ์จะได้รับในบล็อกรหัสต่อไปนี้ สร้างเว็บเพจanimated_bar.html และเพิ่มการเปลี่ยนแปลงต่อไปนี้
<!DOCTYPE html>
<html>
<head>
<style>
.bar {
fill: green;
}
.highlight {
fill: red;
}
.title {
fill: blue;
font-weight: bold;
}
</style>
<script src = "https://d3js.org/d3.v4.min.js"></script>
<title> Animated bar chart </title>
</head>
<body>
<svg width = "500" height = "500"></svg>
<script>
var svg = d3.select("svg"),
margin = 200, width = svg.attr("width") - margin,
height = svg.attr("height") - margin;
svg.append("text")
.attr("transform", "translate(100,0)")
.attr("x", 50).attr("y", 50)
.attr("font-size", "20px")
.attr("class", "title")
.text("Population bar chart")
var x = d3.scaleBand().range([0, width]).padding(0.4),
y = d3.scaleLinear().range([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + 100 + "," + 100 + ")");
d3.csv("data.csv", function(error, data) {
if (error) {
throw error;
}
x.domain(data.map(function(d) { return d.year; }));
y.domain([0, d3.max(data, function(d) { return d.population; })]);
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.append("text")
.attr("y", height - 250)
.attr("x", width - 100)
.attr("text-anchor", "end")
.attr("font-size", "18px")
.attr("stroke", "blue").text("year");
g.append("g")
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "-5.1em")
.attr("text-anchor", "end")
.attr("font-size", "18px")
.attr("stroke", "blue")
.text("population");
g.append("g")
.attr("transform", "translate(0, 0)")
.call(d3.axisLeft(y))
g.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.attr("class", "bar")
.on("mouseover", onMouseOver)
.on("mouseout", onMouseOut)
.attr("x", function(d) { return x(d.year); })
.attr("y", function(d) { return y(d.population); })
.attr("width", x.bandwidth()).transition()
.ease(d3.easeLinear).duration(200)
.delay(function (d, i) {
return i * 25;
})
.attr("height", function(d) { return height - y(d.population); });
});
function onMouseOver(d, i) {
d3.select(this)
.attr('class', 'highlight');
d3.select(this)
.transition()
.duration(200)
.attr('width', x.bandwidth() + 5)
.attr("y", function(d) { return y(d.population) - 10; })
.attr("height", function(d) { return height - y(d.population) + 10; });
g.append("text")
.attr('class', 'val')
.attr('x', function() {
return x(d.year);
})
.attr('y', function() {
return y(d.value) - 10;
})
}
function onMouseOut(d, i) {
d3.select(this)
.attr('class', 'bar');
d3.select(this)
.transition()
.duration(200)
.attr('width', x.bandwidth())
.attr("y", function(d) { return y(d.population); })
.attr("height", function(d) { return height - y(d.population); });
d3.selectAll('.val')
.remove()
}
</script>
</body>
</html>
ตอนนี้ขอเบราว์เซอร์และเราจะเห็นการตอบสนองต่อไปนี้
หากเราเลือกแถบใด ๆ ก็จะถูกเน้นเป็นสีแดง D3 เป็นไลบรารีการแสดงภาพที่มีวัตถุประสงค์ทั่วไปซึ่งเกี่ยวข้องกับการแปลงข้อมูลเป็นข้อมูลเอกสารองค์ประกอบ ฯลฯ และท้ายที่สุดจะช่วยในการสร้างภาพข้อมูล