
lOMoARcPSD| 23136115 
DSDV Mid Note 
1.1. (35pts) Analyze a visualizaon. Analyze and evaluate the visualizaon in Figure 1 by answering 
the following quesons: a. (5pts) What is the goal of the visualizaon?  
b.  (10pts) What is its data? types of data?  
c.  (10pts) How did the author use marks and channels to encode the data?  
d.  (10pts) The design is not good, redesign it.  
(STUDENT ANSWER 1 35/35) 
A, The goal of the visualizaon is to show the probability of near interacon between paents of 
COVID-19 and the stewardess 
B, +, The data is the gures of the probability (%%), which is integer and is shown in terms of color 
scale. 
+, Type of data: aributes 
C, The author has transmied the original data (which is integer) into the darkness of color shown in 
the visualizaon That means the low gures will be represented by light color ( this case is light blue. 
Medium gures are shown in white and the highest are shown in the darkest color ( this case is dark 
pink..). D, The color scale is not good This is how I redesign it. The smallest percentage should be 
shown in the lightest color white. The bigger the percentage is the ‘more blue’ the color gets. The 
color connues to be darker and darker unl it reaches ‘dark blue' at the end of the scale. 
(STUDENT ANSWER 2 35/35) 
a)  This visualizaon is to show the rate of ight aendants and have close-rangecontact with a covid 
paent. 
b)  This is a type of rao, where the auther get the rate of close contact between a ight aendants 
and covid paents on a plane. 
c)  In this visualizaon, the author used squares as a mark on a background of real seats on a plane. 
For the channels, author used hue and saturaon shown below: dark blue - > light blue -> white light 
-> pink dark pink 
d)  As using 2 dierent hues, this visualizaon is a lile bit harder to read by using only 1 hue (which 
I recommend blue as it's cooler and easier to get the change) with a wider range of saturaon, this 
visualizaon may be beer to get the in sight. 

lOMoARcPSD| 23136115 
(GPT ANSWER) 
a.  Goal of the Visualizaon: The goal of the visualizaon is to represent the probability of infecon when 
individuals are in close range with a sick person. This is indicated by the color gradient on an airplane 
seang chart. 
b.  Data and Types of Data: The data consists of the probability percentages of passengers geng infected 
when they are near a sick person. The types of data are categorical (seat labels and indicaons for sick 
person and ight aendant) and quantave (probability percentages). 
c.  Use of Marks and Channels: The author used color as a channel to encode the data, with dierent 
shades represenng dierent probabilies of infecon. Darker colors  indicate higher probabilies. 
Marks are used to represent seats, with special icons indicang the seat occupied by a sick person and 
ight aendants. 
d.  Redesign: To redesign it, I would suggest the following improvements: -  Use  clearer  labels  for 
rows and columns. 
-  Make sure that the color gradient is easily disnguishable for all viewers including those with color 
vision deciencies. 
-  Provide clear legends that explain what each mark and color represents. 
-  Instead of using color alone to represent the probability of infecon, consider using a combinaon 
of color and size. For example, seats with a higher probability of infecon could be represented 
by larger, darker circles, while seats with a lower probability could be represented by smaller, 
lighter circles. This would make the visualizaon more accessible to a wider audience, including 
those with color vision deciencies. 
-  Consider adding interacve elements to the visualizaon. For example, when a user hovers over 
a seat, a toolp could appear showing the exact probability of infecon for that seat. This would 
provide more precise informaon to the user. 
-  Finally, ensure that the visualizaon is responsive so that it can be viewed on devices of dierent 
sizes. This could be achieved by using a exible layout and scalable vector graphics (SVGs). 
1.2. (20pts) Redesign. COVID-I9 is known to be very infecous in closed area like in an aircra cabin. 
The Figure 2 shows a case of COVID-19 spreading in an aircra. However, the visualizaon is not 
compable with gray-scale prinng. 
Your task is to 
a.  Redesign the visualizaon in such a way that could show dierent sroups in a gray-scale prinng. 
b.  Jus your design: the reason for your selecon of marks, channels and others 

lOMoARcPSD| 23136115 
(STUDENT ANSWER 1 20/20)  
a)  Primary group and Secondary group have dierent shapes.  
Ex: Primary. (infecous):   
 Secondary (ight associated):   
The gray-scale channel remains the same in each group (lighter). 
Empty seat will remove gray-scale channel, and add them “-" sign in the Seat: becomes   
b)  Since the design in gray scale will only have 1 color range from white to implythe black-grey-white 
to imply the possibility/infecon, changeing the shape for each group to is a good opon. The idea 
of adding a symbol inside of seat is one good alternave, but it can not be seen with the gray-scale 
aribute, so we can't use this for the "Primary " and "secondary" group, but can be used for "empty 
seat" group, which has been removed the gray-scale channel. 
(STUDENT ANSWER 2 18/20) 
For gray-scale channel, the best way to visualize is using shape 
Rectangle 
Channel: Posion, Dierent shape 
     : Primary (infecous of ight) 
    : Primary (non-infecous of ight) 
: Secondary (ight associated) 
    : Secondary (possible ight associated) 
    : Empty seat 
    : Negave PCR 
(GPT ANSWER) 
Redesigned Visualizaon for Gray-Scale Prinng: 
Economy Class Cabin | Mid Cabin | A Cabin 
------------------------------------------- 
██ Primary (infecous on ight) 
░░ Primary (non-infecous on ight) 
▓▓ Secondary (ight associated) 
▒▒ Secondary (possible ight associated) 
 Empty seat 
XX Negave PCR 
Juscaon for Design: 
Marks and Channels: 

lOMoARcPSD| 23136115 
Primary  (infecous  on  ight):  Used  a  dark  solid ll  (██)  to  indicate high  importance  and  immediate 
aenon. 
Primary (non-infecous on ight): Chose a light paern (░░) to dierenate from infecous but sll signify 
potenal risk. 
Secondary (ight associated): A medium dark paern (▓▓) represents conrmed secondary cases, disnct 
from primary cases. 
Secondary (possible ight associated): A lighter paern (▒▒) suggests uncertainty in the associaon. 
Empty seat: Le blank to show the absence of a passenger. 
Negave PCR: An ‘X’ mark (XX) is universally recognized and indicates a negave test result. 
Reasoning: 
The use of dierent shading paerns allows for clear dierenaon between groups without relying on 
color. 
Paerns are chosen to be disnct enough to avoid confusion when printed in grayscale. 
The symbols are simple and can be easily understood without complex legends or explanaons. 
2. (35pts) Design a visualizaon to show students in a class.  
Each student has a GPA (10pts), a major (10pts), a group’s ID (10pts), and a seat number.  
Show all aributes of each student and show links between all members of a group in the classroom 
arrangement given in Figure 2. 

lOMoARcPSD| 23136115 
(STUDENT ANSWER 1 35/35) 
I will use color, posion and interacve visualizaon for this dataset +, 6 colors are used 
to represent 6 group ID 
Group ID 
color 
1 
red 
2 
orange 
3 
green 
4 
blue 
5 
yellow 
6 
purple 
 +, 3 types of shape are used to represent 3 major 
Major 
Shape 
IT 
rectangle 

lOMoARcPSD| 23136115 
CS 
triagle 
DS 
circle 
+, The shapes are placed exactly at the seat of student 
+, Finally, the size of the shape will represent the GPA of each student. The smallest size stands for 60 
and the biggest will be 100 
+, Any me the printer touch the shape (rectangle, triangle cude), the original gures will be shower 
o. They will consist of: 
-> Group ID 
  -> Major  (interacve visualizaon) 
-> GPA 
(STUDENT ANSWER 2 34/35) 
For showing the student's data in a class, we will use the posion in the class for the "Seat" column, which 
is shown in Figure 2. Therefore, we only need to deal with 3 columns " GPA", "Major" and "GroupID." 
-  The most important column to visualize is Major in my opinion, so I will deal with iirst. 
-  For “Major”, I will use dierent hues for dierent major. For example, red for "IT", blue for "CS", 
and green for "DS" (all of them are in the same level of saturaon, but dierent in hue) 
-  For "GPA", I will put this column to the second level of priority. I will use the saturaon level to 
disnguish between students with high GPA with students with low GPA. 
-  Finally, a number in the middle of the box will show the group that this student belongs to. In this 
case, in order to keep the posion number, I will move them to the top of each box. 
Conclusion: by using 3 channels: posion, hue, saturaon and a number, I will visualize the given data into 
a class diagram 
* For the links between members of a group: all members of a group will have the same number in 
the middle of the box as shown in the rst part, which can be easily disnguished. 
(GPT ANSWER) 
I will use color, posion and interacve visualizaon for this dataset 
+, 6 colors are used to represent 5 range of GPAs 
GPA 
color 
50-59 
red 
60-69 
orange 
70-79 
yellow 
80-89 
green  
90-100 
blue 
 +, 3 types of shape are used to represent 3 major 
Major 
Shape 
IT 
Triangle 
CS 
Circle 
DS 
Square  
+, The shapes are placed exactly at the seat of student 
+, Finally, for the Group ID, we can number 1 to 6 corresponding to the student’s 
Group ID by pung the number at the center of the shape   

lOMoARcPSD| 23136115 
3.  (30pts)  Create  an  HTML  web  page  with  the  tle  “Midterm”.  a.  Get  data  from 
hps://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/ 
csse_covid_19_me_series/me_series_covid19_conrmed_global.csv (in your code, you can refer to this source as 
“covid_global.csv”)  
In the dataset,  
- “Province/State” and “Country/Region” are used as the key for each row. - The date is in US-
format  
Figure 3 is a sample from the dataset.  
Figure 3 - A sample from the dataset  
b. (5pts) Write code to draw a horizontal bar chart to show COVID conrmed cases over the world on “04/04/2022”. 
The chart must 
R1. (5pts) have a xed size (use scale to convert data)  
R2. (5pts) have an axis with a tle and cks  
R3. (5pts) use Province/State and Country/Region as key/label for a row  
R4. (5pts) show only non-zero rows (Use lter funcon of arrays in javascript) R5. (5pts) show 
value in the bar Hint:  
- Use rowConverter  
- Use parseInt, parseFloat to convert strings to numbers - Filter funcon of arrays in javascript. 
newDataSet = dataset.lter(d => d[“04/04/2022”] > 0); 
(ANSWER) 
<!DOCTYPE html> 
<html lang="en"> <head> 
 <meta charset="UTF-8"> 
 <meta name="viewport" content="width=device-width, inial-scale=1.0"> <tle>Midterm</tle> 
 <script src="hps://d3js.org/d3.v7.min.js"></script> </head> 
<body> 
 <div id="chart"></div> 
 <script> 
 // Funcon to convert CSV row to desired data format 
 funcon rowConverter(row) { 

lOMoARcPSD| 23136115 
 return { 
 place: row['Province/State'] + ', ' + row['Country/Region'], 
 cases: +row['4/4/22'] 
 };  
 } 
 // Funcon to draw the chart using D3 
 funcon drawChart(data) { 
 // Dimensions and margins for the chart  const svgWidth = 1500; 
 const svgHeight = 10000; 
 const margin = { top: 10, right: 20, boom: 50, le: 300 }; 
 // Create SVG element 
 const svg = d3.select("#chart") 
 .append("svg") 
 .ar("width", svgWidth) 
 .ar("height", svgHeight) 
 // Dene x and y scales 
 const xScale = d3.scaleLinear() 
 .domain([0, d3.max(data, d => d.cases)]) 
 .range([margin.le, svgWidth - margin.right - 50]); 
 const yScale = d3.scaleBand() 
 .domain(data.map(d => d.place)) 
 .range([margin.top, svgHeight - margin.boom]) 
 .padding(0.1); 
 // Color scale for the bars 
 const colorScale = d3.scaleSequenal() 
 .domain([0, d3.max(data, d => d.cases)]) 
 .interpolator(d3.interpolateYlOrRd); 
 // Dene x and y axes 
 const  xAxis  =  d3.axisBoom(xScale).ck(5);              const  yAxis  = 
d3.axisLe(yScale).ck(5); 
 // Append x axis to SVG 
 svg.append("g") 
 .ar("transform", `translate(5, ${svgHeight - margin.boom + 5})`) 
 .call(xAxis) 
 .append("text") 
 .ar("x", svgWidth - margin.right - 50) .ar("y", - 30) 

lOMoARcPSD| 23136115 
 .ar("font-size", "30px") 
 .ar("font-weight", "bold") .text("Cases") 
 .ar("ll", "black"); 
 // Append y axis to SVG 
 svg.append("g") 
 .ar("transform", `translate(${margin.le}, 0)`) .call(yAxis) 
 .append("text") 
 .ar("x", - 100)  
 .ar("y", 100) 
 .ar("font-size", "30px") 
 .ar("font-weight", "bold") .text("Place") 
 .ar("ll", "black"); 
 // Draw bars on the chart 
 svg.selectAll("rect")         .data(data) 
.enter() 
 .append("rect") 
 .ar("x", margin.le + 5) 
 .ar("y", (d, i) => yScale(d.place)) 
 .ar("width", 0)  .transion()  
 .duraon(700)  
 .ar("width", (d) => xScale(d.cases) - margin.le) 
 .ar("height", yScale.bandwidth()) 
 .ar("ll", (d) => colorScale(d.cases)); 
 // Add labels to the bars 
 svg.selectAll(".label")         .data(data) 
.enter() 
 .append("text") 
 .ar("x", (d) => xScale(d.cases) + 10)  
 .ar("y", (d, i) => yScale(d.place) + yScale.bandwidth() / 2 + 5)  
 .ar("font-family", "sans-serif") .ar("font-size", "11px") 
 .ar("ll",  "white")                  .text((d)  =>  d.cases) 
.transion() 
 .delay(500) 
 .ar("ll", "black"); 

lOMoARcPSD| 23136115 
 } 
 // Load data from CSV and draw the chart 
 d3.csv("me_series_covid19_conrmed_global.csv", rowConverter) .then(data => { 
 // Filter out rows with zero cases 
 data = data.lter(row => row.cases !== 0); 
 drawChart(data); 
 });  
 </script> </body> 
</html> 

lOMoARcPSD| 23136115 
Lab 4 
<!DOCTYPE html> 
<html lang="en"> <head> 
 <meta charset="UTF-8"> 
 <meta name="viewport" content="width=device-width, inial-scale=1.0"> <tle>Lab 4</tle> 
 <script src="hps://d3js.org/d3.v7.min.js"></script> </head> 
<body> 
 <h1>Lab  4  –D3.js  -  Transion,  Update,  Enter  &  Exit</h1>      <h2>Data  science  and  data 
visualizaon</h2> 
 <p>Truong Tri Dung</p> 
 <p>ITCSIU21126</p> 
 <p>This is all my own work. I did not copy the code from any other source.</p> 
 <buon id="addBuon">Add New Province</buon> 
 <buon id="removeBuon">Remove Last Province</buon> 
 <select id="sortSelect"> 
 <opon value="ma">MA</opon> 
 <opon value="area">Area</opon> 
 <opon  value="populaon">Populaon</opon>          <opon 
value="density">Density</opon> 
 <opon value="grdp" selected>GRDP</opon> 
 <opon value="grdp_usd">GRDP (USD)</opon> 
 </select> 
 <div id="chart"></div> 
 <script> 
 var sortValue = "grdp"; //Load data 
 d3.csv("hps://tungth.github.io/data/vn-provinces-data.csv", rowConverter) .then(data => { 
 const dataset = data.slice(0, 20); 
 dataset.sort((a, b) => d3.descending(a[sortValue], b[sortValue])); drawChart(dataset); 
 //Add province buon 
 const addBuon = document.getElementById('addBuon'); 
 let index = 20; 
 addBuon.addEventListener('click', () => { 
 if (index < data.length) { 
 dataset.push(data[index]);  
 dataset.sort((a, b) => d3.descending(a[sortValue], b[sortValue]));  
 d3.select("svg").remove();  
 drawChart(dataset);  

lOMoARcPSD| 23136115 
 index++; 
 } 
 }); 
 //Remove lát province buon 
 const removeBuon = document.getElementById('removeBuon'); 
 removeBuon.addEventListener('click', () => { dataset.pop(); 
 d3.select("svg").remove(); 
 drawChart(dataset); 
 }); 
 d3.select("#sortSelect").on("change", funcon() { 
 sortValue = d3.select(this).property("value"); 
 dataset.sort((a, b) => d3.descending(a[sortValue], b[sortValue])); 
 d3.select("svg").remove(); 
 drawChart(dataset); 
 }); 
 });  
 // Converts each row of the CSV data into an object with specic properes  funcon rowConverter(row) { 
 // Converts strings to numbers where necessary  return { 
 ma: +row.ma, 
 province: row.province, 
 area: +row.area, 
 populaon: +row.populaon, density: +row.density, 
 grdp: parseFloat(row['GRDP-VND'].replace(',', '.')),  
 grdp_usd: parseFloat(row['GRDP-USD'].replace(',', '.'))  
 }; 
 } 
 // Draws the chart based on the provided data 
 funcon drawChart(data) { 
 // Denes dimensions and margins for the SVG element  const svgWidth = 1000; 
 const svgHeight = 650; 
 const margin = { top: 10, right: 20, boom: 50, le: 70 }; 
 // Selects the chart div and appends an SVG element to it  const svg = d3.select("#chart") 
 .append("svg") 

lOMoARcPSD| 23136115 
 .ar("width", svgWidth) 
 .ar("height", svgHeight) 
 // Denes scales for x and y axes 
 const xScale = d3.scaleLinear() 
 .domain([0, d3.max(data, d => d[sortValue])]) 
 .range([margin.le, svgWidth - margin.right - 50]); 
 const yScale = d3.scaleBand() 
 .domain(data.map(d => d[sortValue])) 
 .range([margin.top, svgHeight - margin.boom]) 
 .padding(0.1); 
 //  Denes  color  scale  based  on  data  values              const  colorScale  = 
d3.scaleSequenal() 
 .domain([0, d3.max(data, d => d[sortValue])]) 
 .interpolator(d3.interpolateYlOrRd); 
 // Denes x and y axes 
 const xAxis = d3.axisBoom(xScale); 
 const yAxis = d3.axisLe(yScale).ckFormat(d3.format(".2f")); 
 // Appends x-axis to the SVG and adds label 
 svg.append("g") 
 .ar("transform", `translate(5, ${svgHeight - margin.boom + 5})`) 
 .call(xAxis) 
 .append("text") 
 .ar("x", svgWidth / 2) .ar("y", 40) 
 .ar("font-weight", "bold") .text( 
 sortValue == "grdp" ? "GRDP in VND" :  
 sortValue == "grdp_usd" ? "GRDP in USD" :  
 sortValue == "populaon" ? "Populaon" : 
 sortValue == "area" ? "Area" : 
 sortValue == "density" ? "Density" : "MA"  ) 
 .ar("ll", "black"); 
 // Appends y-axis to the SVG and adds label 
 svg.append("g") 
 .ar("transform", `translate(${margin.le}, 0)`) .call(yAxis) 
 .append("text") 
 .ar("transform", "rotate(-90)") 

lOMoARcPSD| 23136115 
 .ar("font-weight", "bold")  .ar("x", - 200) 
 .ar("y", - 50) .text( 
 sortValue == "grdp" ? "Sorted by GRDP in VND" :  
 sortValue == "grdp_usd" ? "Sorted by GRDP in USD" : 
 sortValue == "populaon" ? "Sorted by Populaon" : 
 sortValue == "area" ? "Sorted by Area" : 
 sortValue == "density" ? "Sorted by Density" : "Sorted by MA"  ) 
 .ar("ll", "black"); 
 // Appends bars to the SVG represenng data points 
 svg.selectAll("rect")         .data(data) 
.enter() 
 .append("rect") 
 .ar("x", margin.le + 5) 
 .ar("y", (d, i) => yScale(d[sortValue])) 
 .ar("width", 0) .transion()  
 .duraon(700)  
 .ar("width", (d) => xScale(d[sortValue]) - margin.le) 
 .ar("height", yScale.bandwidth()) 
 .ar("ll", (d) => colorScale(d[sortValue])); 
 // Appends labels to the SVG near the bars 
 svg.selectAll(".label")  .data(data) 
.enter() 
 .append("text") 
 .ar("x", (d) => xScale(d[sortValue]) + 10)  
 .ar("y", (d, i) => yScale(d[sortValue]) + yScale.bandwidth() / 2 + 5)  
 .ar("font-family", "sans-serif")  .ar("font-size", "11px") 
 .ar("ll", "white") 
 .text((d) => d.province) .transion() 
 .delay(500) 
 .ar("ll", "black"); 
 } 
 </script> </body> 
</html> 

lOMoARcPSD| 23136115 
Lab 3 
<!DOCTYPE html> 
<html lang="en"> <head> 
 <meta charset="UTF-8"> 
 <meta name="viewport" content="width=device-width, inial-scale=1.0"> <tle>Lab 3</tle> 
 <link rel="stylesheet" href="styles.css"> 
</head> 
<body> 
 <div id="container"> <h1>Lab 3</h1> 
 <p>Name: Ta Trung Hieu</p> 
 <p>Student ID: ITCSIU21180</p> 
 <p>Course Title: Data science and data visualizaon</p> 
 <p>Lab Title: Lab 3 – D3.js - scales</p> 
 <p>This is all my own work. I did not copy the code from any other source.</p> 
 <svg id="chart"></svg> 
 </div> 
 <script> 
 // Read CSV le and draw chart 
 d3.csv("hps://tungth.github.io/data/vn-provinces-data.csv", rowConverter)             .then(data =>  {  //  When  data is loaded 
successfully 
 console.log(data); // Log the loaded data to the console 
 drawChart(data); // Call the drawChart funcon with the loaded data  }); 
 // Funcon to convert each row of data 
 funcon rowConverter(d) { return { 
 province: d.province, // Convert province to string 
 populaon: +d.populaon, // Convert populaon to number 
 grdp: parseFloat(d['GRDP-VND'].replace(',', '.')), // Convert GRDP-VND to number, replacing commas with dots 
 area: +d.area // Convert area to number 
 }; 
 } 
 // Funcon to draw the chart using the provided data 
 funcon drawChart(data) { 
 // Dene SVG dimensions and margins 
 const svgWidth = 600; 
 const svgHeight = 400; 
 const margin = { top: 20, right: 20, boom: 50, le: 80 }; 

lOMoARcPSD| 23136115 
 const chartWidth = svgWidth - margin.le - margin.right; 
 const chartHeight = svgHeight - margin.top - margin.boom; 
 // Create SVG element 
 const svg = d3.select("#chart") 
 .ar("width", svgWidth) 
 .ar("height", svgHeight); 
 // Dene scales for x, y, area, and color 
 const xScale = d3.scaleLinear() 
 .domain(d3.extent(data, d => d.populaon)) // Domain based on populaon data 
 .range([margin.le, svgWidth - margin.right]); 
 const yScale = d3.scaleLinear() 
 .domain([0, 180]) // Fixed domain for GRDP-VND 
 .range([svgHeight - margin.boom, margin.top]); 
 const areaScale = d3.scaleSqrt() 
 .domain(d3.extent(data, d => d.area)) // Domain based on area data 
 .range([3, 12]); // Range for circle radius 
 const colorScale = d3.scaleSequenal() 
 .domain(d3.extent(data, d => d.populaon / d.area)) // Domain based on populaon/area rao 
 .interpolator(d3.interpolateTurbo); // Color interpolaon 
 // Draw circles for each data point 
 svg.selectAll("circle")         .data(data) 
.enter() 
 .append("circle") 
 .ar("cx", d => xScale(d.populaon)) 
 .ar("cy", d => yScale(d.grdp)) 
 .ar("r", d => areaScale(d.area)) 
 .ar("ll", d => colorScale(d.populaon / d.area)); 
 // Create x and y axis 
 const  xAxis  =  d3.axisBoom(xScale);              const  yAxis  = 
d3.axisLe(yScale); 
 // Append x-axis to SVG 
 svg.append("g") 
 .ar("transform", `translate(0,${svgHeight - margin.boom})`) .call(xAxis) 
 .append("text") 

lOMoARcPSD| 23136115 
 .ar("x", chartWidth) // Posion text at the end of the x-axis 
 .ar("y", -10) 
 .ar("text-anchor", "end") 
 .text("Populaon"); 
 // Append y-axis to SVG 
 svg.append("g") 
 .ar("transform", `translate(${margin.le},0)`) .call(yAxis) 
 .append("text") 
 .ar("transform", "rotate(-90)") 
 .ar("y", chartWidth / 2) // Posion text at the middle of the y-axis  .ar("x", -chartHeight / 2) 
 .ar("dy", "-2em") // Oset text from axis  .ar("text-anchor", "middle") 
 .text("GRDP-VND (million VND/person/year)"); 
 } 
 </script> 
</body> 
</html> 
                            Bấm  Tải xuống để xem toàn bộ.
                        
                                                    
                                                                            Preview text:
id="chart">