Skip to content

Instantly share code, notes, and snippets.

@hungvietdo
Last active February 16, 2016 01:56
Show Gist options
  • Save hungvietdo/2c38eed928999266bf0b to your computer and use it in GitHub Desktop.
Save hungvietdo/2c38eed928999266bf0b to your computer and use it in GitHub Desktop.
Magnitude and Identify
var testData = [
{times: [{"starting_time": 1355752800000, "ending_time": 1355759900000}, {"starting_time": 1355769900000, "ending_time": 1355774400000}]},
{times: [{"starting_time": 1355752800000, "ending_time": 1355761900000}, {"starting_time": 1355767500000, "ending_time": 1355774400000}]},
{times: [{"starting_time": 1355752800000, "ending_time": 1355763910000}]},
];
var width = 500;
var chart = d3.timeline().showAxisTop().stack();
var svg = d3.select("#header1").append("svg").attr("width", width)
.datum(testData).call(chart);
var w = 700,
h = 400,
margin = { top: 50, right: 20, bottom: 20, left: 40 },
svg = d3.select("#header2").append("svg").attr("width", w).attr("height", h);
d3.csv('data.csv', function(error, data) {
data.forEach(function(d) {
d.temp = +d["Max TemperatureF"];
d.date = d["EST"];
});
//Hung Do: parse the date in text to real_date
var parseDate = d3.time.format("%Y-%m-%d").parse;
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var xScale = d3.time.scale()
.domain([d3.time.day.offset(data[0].date,-1),d3.time.day.offset(data[data.length-1].date,1)])
.range([margin.left, w - margin.right]); // Set margins for x specific
var yScale = d3.scale.linear()
.domain([0, d3.max(data, function (d) { return d.temp + 10; })])
.range([margin.top, h - margin.bottom]); // Set margins for y specific
// Add a X and Y Axis (Note: orient means the direction that ticks go, not position)
var xAxis = d3.svg.axis().scale(xScale)
.orient("top")
.tickFormat(d3.time.format("%a %d"))
.ticks(d3.time.days, 1);
var yAxis = d3.svg.axis().scale(yScale).orient("left");
var rectAttrs = {
x: function(d) { return xScale(d.date)-10; },
y: function(d) { return yScale(d.temp)-10; },
width: function(d) { return d.temp-10; },
height: function(d) { return d.temp-10; },
fill: "green"
};
svg.append("g").attr({
"class": "x axis", // Give class so we can style it
transform: "translate(" + [0, margin.top] + ")" // Translate just moves it down into position (or will be on top)
}).call(xAxis)
; // Call the xAxis function on the group
// Adds Y-Axis as a 'g' element
svg.append("g").attr({
"class": "axis",
transform: "translate(" + [margin.left, 0] + ")"
}).call(yAxis); // Call the yAxis function on the group
svg.append("text")
.attr("text-anchor", "end") // this makes it easy to centre the text as the transform is applied to the anchor
.attr("transform", "translate("+ (80) +","+(h-100)+")rotate(-90)") // text is drawn off the screen top left, move down and out and rotate
.text("Temperature (F)");
svg.append("text")
.attr("text-anchor", "end") // this makes it easy to centre the text as the transform is applied to the anchor
.attr("transform", "translate("+ (w) +","+(margin.top+20)+")") // centre below axis
.text("Week February 7-13, 2016");
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr(rectAttrs) // Get attributes from circleAttrs var
.on("mouseover", handleMouseOver)
.on("mouseout", handleMouseOut)
;
var formatDate = d3.time.format("%a %d");
// Create Event Handlers for mouse
function handleMouseOver(d, i) { // Add interactivity
// Use D3 to select element, change color and size
d3.select(this).attr({
fill: "orange"
});
// Specify where to put label of text
svg.append("text").attr({
id: "t" + d.x + "-" + d.y + "-" + i, // Create an id for text so we can select it later for removing on mouseout
x: function() { return xScale(d.date) - 20; },
y: function() { return yScale(d.temp) - 20; }
})
.text(function() {
return [ d.temp +"F on "+ formatDate(d.date) ]; // Value of the text
});
}
function handleMouseOut(d, i) {
// Use D3 to select element, change color back to normal
d3.select(this).attr({
fill: "green"
});
// Select text by id and then remove
d3.select("#t" + d.x + "-" + d.y + "-" + i).remove(); // Remove text location
}
});
var w = 700,
h = 400,
margin = { top: 30, right: 20, bottom: 20, left: 60 },
svg3 = d3.select("#header3").append("svg").attr("width", w).attr("height", h);
d3.csv('data.csv', function(error, data) {
data.forEach(function(d) {
d.temp = +d["Max TemperatureF"];
d.tempmin = +d["Min TemperatureF"];
d.tempmean = +d["Mean TemperatureF"];
d.date = d["EST"];
});
//Hung Do: parse the date in text to real_date
var parseDate = d3.time.format("%Y-%m-%d").parse;
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var formatDate = d3.time.format("%a %d");
var xScale = d3.time.scale()
.domain([d3.time.day.offset(data[0].date,-1),d3.time.day.offset(data[data.length-1].date,1)])
.range([margin.left, w - margin.right]); // Set margins for x specific
// We're passing in a function in d3.max to tell it what we're maxing (y value)
var yScale = d3.scale.linear()
.domain([0, d3.max(data, function (d) { return d.temp + 10; })])
.range([margin.top, h - margin.bottom]); // Set margins for y specific
// Add a X and Y Axis (Note: orient means the direction that ticks go, not position)
var xAxis = d3.svg.axis().scale(xScale)
.orient("top")
.tickFormat(d3.time.format("%a %d"))
.ticks(d3.time.days, 1)
;
var yAxis = d3.svg.axis().scale(yScale).orient("left");
// Adds X-Axis as a 'g' element
svg3.append("g").attr({
"class": "x axis", // Give class so we can style it
transform: "translate(" + [0, margin.top] + ")" // Translate just moves it down into position (or will be on top)
}).call(xAxis);
svg3.append("text")
.attr("text-anchor", "end") // this makes it easy to centre the text as the transform is applied to the anchor
.attr("transform", "translate("+ (80) +","+(h-100)+")rotate(-90)") // text is drawn off the screen top left, move down and out and rotate
.text("Temperature (F)");
svg3.append("text")
.attr("text-anchor", "end") // this makes it easy to centre the text as the transform is applied to the anchor
.attr("transform", "translate("+ (w) +","+(margin.top+20)+")") // centre below axis
.text("Week February 7-13, 2016");
// Adds Y-Axis as a 'g' element
svg3.append("g").attr({
"class": "axis",
transform: "translate(" + [margin.left, 0] + ")"
}).call(yAxis); // Call the yAxis function on the group
var rectAttrs = {
cx: function(d) { return xScale(d.date)-10; },
cy: function(d) { return yScale(d.temp)-10; },
r: 5,
fill: "green"
};
var rectAttrsmin = {
cx: function(d) { return xScale(d.date)-10; },
cy: function(d) { return yScale(d.tempmin)-10; },
r: 5,
fill: "red"
};
var rectAttrsmean = {
cx: function(d) { return xScale(d.date)-10; },
cy: function(d) { return yScale(d.tempmean)-10; },
r: 5,
fill: "blue"
};
var ordinal = d3.scale.ordinal()
.domain(["Lowest Temperature", "Mean Temperature", "Highest Temperature"])
.range([ "red","blue","green"]);
svg3.append("g")
.attr("class", "legendOrdinal")
.attr("transform", "translate("+w/2+", "+(h-40)+")");
var legendOrdinal = d3.legend.color()
.shape("path", d3.svg.symbol().type("triangle-up").size(150)())
.shapePadding(120)
.labelOffset(10)
.scale(ordinal)
.cells(3)
.orient('horizontal')
;
svg3.select(".legendOrdinal")
.call(legendOrdinal);
svg3.selectAll("rect1")
.data(data)
.enter()
.append("circle")
.attr(rectAttrs)
.on("mouseover", handleMouseOver)
.on("mouseout", handleMouseOut)
;
svg3.selectAll("rect2")
.data(data)
.enter()
.append("circle")
.attr(rectAttrsmin)
.on("mouseover", handleMouseOvermin)
.on("mouseout", handleMouseOutmin)
;
svg3.selectAll("rect3")
.data(data)
.enter()
.append("circle")
.attr(rectAttrsmean)
.on("mouseover", handleMouseOvermean)
.on("mouseout", handleMouseOutmean)
;
// Hung Do: mouse move high temprature
function handleMouseOver(d, i) { // Add interactivity
d3.select(this).attr({
fill: "orange"
});
svg3.append("text").attr({
id: "t" + d.x + "-" + d.y + "-" + i,
x: function() { return xScale(d.date) - 20; },
y: function() { return yScale(d.temp) - 20; }
})
.text(function() {
return [ d.temp +"F on "+ formatDate(d.date) ];
});
}
function handleMouseOut(d, i) {
d3.select(this).attr({
fill: "green"
});
d3.select("#t" + d.x + "-" + d.y + "-" + i).remove();
}
function handleMouseOvermin(d, i) {
d3.select(this).attr({
fill: "orange"
});
svg3.append("text").attr({
id: "t" + d.x + "-" + d.y + "-" + i, // Create an id for text so we can select it later for removing on mouseout
x: function() { return xScale(d.date) - 20; },
y: function() { return yScale(d.tempmin) - 20; }
})
.text(function() {
return [ d.tempmin +"F on "+ formatDate(d.date) ]; // Value of the text
});
}
function handleMouseOutmin(d, i) {
// Use D3 to select element, change color back to normal
d3.select(this).attr({
fill: "red"
});
// Select text by id and then remove
d3.select("#t" + d.x + "-" + d.y + "-" + i).remove(); // Remove text location
}
function handleMouseOvermean(d, i) {
d3.select(this).attr({
fill: "orange"
});
svg3.append("text").attr({
id: "t" + d.x + "-" + d.y + "-" + i, // Create an id for text so we can select it later for removing on mouseout
x: function() { return xScale(d.date) - 20; },
y: function() { return yScale(d.tempmean) - 20; }
})
.text(function() {
return [ d.tempmean +"F on "+ formatDate(d.date) ]; // Value of the text
});
}
function handleMouseOutmean(d, i) {
// Use D3 to select element, change color back to normal
d3.select(this).attr({
fill: "blue"
});
// Select text by id and then remove
d3.select("#t" + d.x + "-" + d.y + "-" + i).remove(); // Remove text location
}
});
var w = 700,
h = 400,
margin = { top: 30, right: 100, bottom: 20, left: 60 },
svg4 = d3.select("#header4").append("svg").attr("width", w).attr("height", h);
d3.csv('data.csv', function(error, data) { // NEW
data.forEach(function(d) { // NEW
d.temp = +d["Max TemperatureF"];
d.tempmin = +d["Min TemperatureF"];
d.tempmean = +d["Mean TemperatureF"];
d.date = d["EST"];
// NEW
}); // NEW
//Hung Do: parse the date in text to real_date
var parseDate = d3.time.format("%Y-%m-%d").parse;
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var formatDate = d3.time.format("%a %d");
// We're passing in a function in d3.max to tell it what we're maxing (x value)
// var xScale = d3.scale.linear()
// .domain([data[0].date,data[data.length-1].date])
// .range([margin.left, w - margin.right]); // Set margins for x specific
var xScale = d3.time.scale()
.domain([d3.time.day.offset(data[0].date,-1),d3.time.day.offset(data[data.length-1].date,1)])
.range([margin.left, w - margin.right]); // Set margins for x specific
// We're passing in a function in d3.max to tell it what we're maxing (y value)
var yScale = d3.scale.linear()
.domain([10, d3.max(data, function (d) { return d.temp + 10; })])
.range([margin.top, h - margin.bottom]); // Set margins for y specific
// Add a X and Y Axis (Note: orient means the direction that ticks go, not position)
var xAxis = d3.svg.axis().scale(xScale)
.orient("top")
.tickFormat(d3.time.format("%a %d"))
.ticks(d3.time.days, 1)
;
var yAxis = d3.svg.axis().scale(yScale).orient("left");
// Adds X-Axis as a 'g' element
svg4.append("g").attr({
"class": "x axis", // Give class so we can style it
transform: "translate(" + [0, margin.top] + ")" // Translate just moves it down into position (or will be on top)
}).call(xAxis);
svg4.append("text")
.attr("text-anchor", "end")
.attr("transform", "translate("+ (80) +","+(h-100)+")rotate(-90)")
.text("Temperature (F)");
svg4.append("text")
.attr("text-anchor", "end")
.attr("transform", "translate("+ (w) +","+(margin.top+20)+")")
.text("Week February 7-13, 2016");
var linearSize = d3.scale.linear().domain([0,10]).range([3, 13]);
svg4.append("g")
.attr("class", "legendSize")
.attr("transform", "translate("+w/2+", "+(h-40)+")");
var legendSize = d3.legend.size()
.scale(linearSize)
.shape('circle')
.shapePadding(15)
.labelOffset(20)
.cells(3)
.labels(["Low","Mean","High"])
.orient('horizontal');
svg4.select(".legendSize")
.call(legendSize);
// Adds Y-Axis as a 'g' element
svg4.append("g").attr({
"class": "axis",
transform: "translate(" + [margin.left, 0] + ")"
}).call(yAxis); // Call the yAxis function on the group
var rectAttrs = {
cx: function(d) { return xScale(d.date)-10; },
cy: function(d) { return yScale(d.temp)-10; },
r: 13,
fill: "orange"
};
var rectAttrsmin = {
cx: function(d) { return xScale(d.date)-10; },
cy: function(d) { return yScale(d.tempmin)-10; },
r: 3,
fill: "orange"
};
var rectAttrsmean = {
cx: function(d) { return xScale(d.date)-10; },
cy: function(d) { return yScale(d.tempmean)-10; },
r: 7,
fill: "orange"
};
svg4.selectAll("rect1")
.data(data)
.enter()
.append("circle")
.attr(rectAttrs)
.on("mouseover", handleMouseOver)
.on("mouseout", handleMouseOut)
;
svg4.selectAll("rect2")
.data(data)
.enter()
.append("circle")
.attr(rectAttrsmin)
.on("mouseover", handleMouseOvermin)
.on("mouseout", handleMouseOutmin)
;
svg4.selectAll("rect3")
.data(data)
.enter()
.append("circle")
.attr(rectAttrsmean)
.on("mouseover", handleMouseOvermean)
.on("mouseout", handleMouseOutmean)
;
// Hung Do: mouse move high temprature
function handleMouseOver(d, i) { // Add interactivity
d3.select(this).attr({
fill: "blue"
});
svg4.append("text").attr({
id: "t" + d.x + "-" + d.y + "-" + i,
x: function() { return xScale(d.date) - 20; },
y: function() { return yScale(d.temp) - 30; }
})
.text(function() {
return [ d.temp +"F on "+ formatDate(d.date) ];
});
}
function handleMouseOut(d, i) {
d3.select(this).attr({
fill: "orange"
});
d3.select("#t" + d.x + "-" + d.y + "-" + i).remove();
}
function handleMouseOvermin(d, i) {
d3.select(this).attr({
fill: "blue"
});
svg4.append("text").attr({
id: "t" + d.x + "-" + d.y + "-" + i, // Create an id for text so we can select it later for removing on mouseout
x: function() { return xScale(d.date) - 20; },
y: function() { return yScale(d.tempmin) - 20; }
})
.text(function() {
return [ d.tempmin +"F on "+ formatDate(d.date) ]; // Value of the text
});
}
function handleMouseOutmin(d, i) {
// Use D3 to select element, change color back to normal
d3.select(this).attr({
fill: "orange"
});
// Select text by id and then remove
d3.select("#t" + d.x + "-" + d.y + "-" + i).remove(); // Remove text location
}
function handleMouseOvermean(d, i) {
d3.select(this).attr({
fill: "blue"
});
svg4.append("text").attr({
id: "t" + d.x + "-" + d.y + "-" + i, // Create an id for text so we can select it later for removing on mouseout
x: function() { return xScale(d.date) - 20; },
y: function() { return yScale(d.tempmean) - 20; }
})
.text(function() {
return [ d.tempmean +"F on "+ formatDate(d.date) ]; // Value of the text
});
}
function handleMouseOutmean(d, i) {
// Use D3 to select element, change color back to normal
d3.select(this).attr({
fill: "Orange"
});
// Select text by id and then remove
d3.select("#t" + d.x + "-" + d.y + "-" + i).remove(); // Remove text location
}
});

Submission for VI4

Student

  • Hung Do; CS725:Information Visualization; Spring 2016;
  • Computer Science; Old Dominion University

First part

Using D3 to create visualizations. Detail: http://bl.ocks.org/hungvietdo/raw/2c38eed928999266bf0b/

Second part

I used Tableau to create visualizations.

First question: magnitude as position on a common scale

  • Looking at the x-axis (time) of the chart we can compare the period of each task in a project gantt chart.
  • Property of discriminability: there are two bins in this type of chart color (type of task) and the width of task (how long).

Question 1

Second question: magnitude as area

  • This is channel in magnitude which use area to represent different temperature during the week. The smaller of rectange, the lower of temperature.
  • Property of discriminability: size and position of the rectanges. But clearly, these two bins are not quite right for human perception of discirminability.

Question 2

Third question: identity as color hue

  • This channel use hue color to categorize three different temperature groups (high, mean, min).
  • Property of discriminability: hue color and position are used to define the data item.

Question 3

Fourth question: identity as spatial region

  • Using spatial region to show different groups of temperatures.
  • Property of discriminability: size of the data item.

Question 4

EST Max TemperatureF Mean TemperatureF Min TemperatureF Max Dew PointF MeanDew PointF Min DewpointF Max Humidity Mean Humidity Min Humidity Max Sea Level PressureIn Mean Sea Level PressureIn Min Sea Level PressureIn Max VisibilityMiles Mean VisibilityMiles Min VisibilityMiles Max Wind SpeedMPH Mean Wind SpeedMPH Max Gust SpeedMPH PrecipitationIn CloudCover Events WindDirDegrees
2016-2-7 42 38 34 32 29 25 76 64 51 30.24 29.98 29.68 10 10 10 28 18 38 0.03 5 Rain 18
2016-2-8 46 42 38 37 31 25 76 65 54 29.78 29.71 29.62 10 10 10 28 10 36 T 4 Rain 21
2016-2-9 50 44 37 39 32 16 89 64 39 29.73 29.59 29.53 10 10 8 17 7 24 0.01 7 Rain 266
2016-2-10 42 36 30 17 14 9 58 45 32 29.97 29.83 29.72 10 10 10 18 9 26 0.00 3 263
2016-2-11 35 30 25 9 5 2 46 36 26 30.32 30.14 29.99 10 10 10 16 8 25 0.00 0 291
2016-2-12 31 28 25 23 17 7 81 60 39 30.33 30.14 30.00 10 8 1 14 5 17 0.04 5 Snow 56
2016-2-13 32 26 20 21 6 -6 81 51 21 30.45 30.22 30.01 10 10 10 20 10 31 0.00 1 330
html,body,#wrapper {
width: 80%;
height: 80%;
margin: 0px;
padding: 5px 5px 5px 5px;
padding-top: 20px;
}
.chart {
font-family: Arial, sans-serif;
font-size: 12px;
}
.axis path,.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: #33b5e5;
}
.bar-failed {
fill: #CC0000;
}
.bar-running {
fill: #669900;
}
.bar-succeeded {
fill: #33b5e5;
}
.bar-killed {
fill: #ffbb33;
}
#header1 {
position: center;
top: 0;
left: 10px;
z-index: 10;
}
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.timeline-label {
font-family: sans-serif;
font-size: 12px;
}
.coloredDiv {
height:20px; width:20px; float:left;
}
.right {
float: left;
width: 400px;
margin: 10px 0px 0px 30px ;
}
<!DOCTYPE html>
<html>
<head>
<link type="text/css" href="http://mbostock.github.io/d3/style.css" rel="stylesheet" />
<link type="text/css" href="example.css" rel="stylesheet" />
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.8.0/d3-legend.js"></script>
<script src="https://raw.githubusercontent.com/jiahuang/d3-timeline/master/src/d3-timeline.js"></script>
</head>
<body>
<div>
<h3 >First Question: magnitude as position on a common scale. </h3>
<div width="100%" id="header1"> </div>
<div class="right">
Sample from: <a href="https://github.com/jiahuang/d3-timeline">https://github.com/jiahuang/d3-timeline</a>
</div>
<br><br><br><br><br><br>
<h3 >Second Question: magnitude as area. </h3>
Norfolk's weather last week (Feb 7-13). Data: <a href="http://www.wunderground.com/history/airport/KORF/2016/2/13/WeeklyHistory.html?req_city=&req_state=&req_statename=&reqdb.zip=&reqdb.magic=&reqdb.wmo=&MR=1" target="_blank">http://www.wunderground.com/history/airport/KORF/2016/2/13/WeeklyHistory.html</a>
<div width="100%" id="header2"> </div>
<br><br><br><br><br><br>
<h3 >Third Question: identity as color hue. </h3>
<div width="100%" id="header3"> </div>
<br><br><br><br><br><br>
<h3 >Fourth Question: identity as spatial region. </h3>
<div width="100%" id="header4"> </div>
<br><br><br><br><br><br>
<h3>Refereces: </h3>
- Gantt chart: <a href="https://github.com/jiahuang/d3-timeline">https://github.com/jiahuang/d3-timeline</a> <br>
- Legend: <a href="http://d3-legend.susielu.com/#color" target="_blank">http://d3-legend.susielu.com/#color</a><br>
- Mouse hover: <a href="http://bl.ocks.org/mbostock/3902569" target="_blank">http://bl.ocks.org/mbostock/3902569</a><br>
- Read csv file: <a href="http://learnjsdata.com/read_data.html" target="_blank">http://learnjsdata.com/read_data.html</a><br>
<script type="text/javascript" src="1stq.js"></script>
<script type="text/javascript" src="2ndq.js"></script>
<script type="text/javascript" src="3rd.js"></script>
<script type="text/javascript" src="4th.js"></script>
<div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment