Visualizations are an intrinsic component in conveying information. They are the end result of all of the C#, SQL, JavaScript, and API calls. I have plenty of experience writing both JavaScript and D3.js to convey visual information in dashboards. The example direclty below is the source code I have written for a line chart.
.barTwo {
fill: navy
}
.barTwo:hover {
fill: lightblue
}
.barThree {
fill: darkred
}
.barThree:hover {
fill: lightgrey
}
#slider {
max-width: 80%;
margin-left: 1%;
margin-bottom: 1%;
background-color: #c1ccde;
}
#sliderTwo {
color: darkgrey;
font-family: arial;
font-size: 14px;
}
.toolTip {
position: absolute;
display: none;
min-width: 80px;
height: auto;
background: none repeat scroll 0 0 azure;
border: 1px solid navy;
border-radius: 10px;
font-family: Arial,Helvetica Neue,Helvetica;
font-size: 12px;
padding: 7px;
text-align: center;
}
#button-container {
display: inline-block;
position: relative;
width: 100%;
}
#play-button {
margin: 1% 1% 1% 1%;
-moz-transition: all .5s ease-in;
-o-transition: all .5s ease-in;
-webkit-transition: all .5s ease-in;
transition: all .5s ease-in;
background: #5068bf;
border-radius: 6px;
border: none;
color: white;
margin: 0;
padding: 0 12px;
width: 60px;
cursor: pointer;
height: 30px;
}
#play-button:hover {
background-color: #91b2c9;
}
#reset-button {
margin: 1% 1% 1% 1%;
-moz-transition: all .5s ease-in;
-o-transition: all .5s ease-in;
-webkit-transition: all .5s ease-in;
transition: all .5s ease-in;
background: #5d5c78;
border-radius: 6px;
border: none;
color: white;
margin: 0;
padding: 0 12px;
width: 60px;
cursor: pointer;
height: 30px;
}
#reset-button:hover {
background-color: #8c8aab;
}
#selectButton {
margin: 1% 1% 1% 1%;
background: #5d5c78;
border-radius: 6px;
border: none;
color: white;
margin: 0;
padding: 0 12px;
width: 60px;
cursor: pointer;
height: 30px;
}
#seconds {
margin: 1% 1% 1% 1%;
background: #5e79db;
border-radius: 6px;
border: none;
color: white;
margin: 0;
padding: 0 12px;
width: 130px;
cursor: pointer;
height: 30px;
}
var margin = { top: 30, right: 10, bottom: 30, left: 45 },
width = 800 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;
var svg = d3.select("#MyChart").append("svg")
.attr('preserveAspectRatio', 'xMinYMin meet')
.attr(
'viewBox',
'0 0 ' +
(width + margin.left + margin.right) +
' ' +
(height + margin.top + margin.bottom)
)
//.style("border", "1px solid grey")
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// var LegendTest = d3.select("body").append("svg")
// .attr("width", 200)
// .attr("height", 200)
// .style("border", "1px solid grey")
// // .selectAll("g")
// GLOBAL VARIABLES
// ==========================================================
var inter;
var nested;
var MySales;
var MyYear;
var selectedFruit = 0; // so it has default value
var i = -1;
var LegendTransitionTime = 1700;
var IntervalSecondDelay = 1000;
// Min Max Year Global Variables
var YearArray = [];
var YearIndex = [];
var MinYear;
var MaxYear;
var legend;
var tooltip = d3.select("body").append("div").attr("class", "toolTip");
// INITIAL FUNCTION
//=======================================================================
GetMinMaxYears()
function GetMinMaxYears() {
d3.json("https://api.myjson.com/bins/j8u3o").then(function (data) {
nested = d3.nest()
.key(function (d) { return d.Year })
.rollup(v =>
v.map(elem =>
({ key: elem["Airline"], value: Number(elem["Sales"]) })
)
)
.entries(data);
let airlines = nested.filter(x => x.key === nested[1].key)[0].value;
var colorScale = d3.scaleOrdinal()
.domain(airlines.map(function (d, i) { return i }))
.range(["#b3d1ff", "#80b3ff", "#4d94ff", "#0052cc", "#002966"])
legend = svg.append("svg")
// .attr("width", 2000)
// .attr("height", 110)
.selectAll("g")
.data(airlines)
.enter().append("g")
.attr("transform", function (d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("circle")
.attr("cx", 5)
.attr("cy", 5)
.attr("r", 6)
.attr("transform", "translate(638, 4)")
.style("fill", function (d) { return colorScale(d.key) });
legend
.append("text")
.attr("transform", "translate(630, 0)")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("font-family", "Arial,Helvetica Neue,Helvetica")
.style("font-size", "10px")
.attr("fill", "#484848")
.text(function (d) { return d.key })
for (var i = 0; i < nested.length; i++) {
YearArray.push(nested[i].key);
}
MinYear = Math.min.apply(Math, YearArray);
MaxYear = Math.max.apply(Math, YearArray);
for (var i = 0; i < YearArray.length; i++) {
YearIndex.push(i);
}
d3.select("#selectButton")
.selectAll('myOptions')
.data(nested)
.enter()
.append("option")
.text(function (d) { return d.key; })
.attr("value", function (d) { return d.key; })
// .attr("value", function (d, i) { return i; })
d3.select('#selectButton').on('change', function (d, i) {
// Change the current key and call the function to update the colors.
selectedFruit = this.options[this.selectedIndex].index;
let airlines = nested.filter(x => x.key === nested[selectedFruit].key)[0].value;
// document.getElementById("sliderTwo").innerHTML = "Current Year " +
// ""+ nested[selectedFruit].key + ""
MySelectBox(airlines)
})
});}
d3.json("https://api.myjson.com/bins/j8u3o").then(function (data) {
nested = d3.nest()
.key(function (d) { return d.Year })
.rollup(v =>
v.map(elem =>
({ key: elem["Airline"], value: Number(elem["Sales"]) })
)
)
.entries(data);
// ADD INDEX HERE
let airlines = nested.filter(x => x.key === nested[0].key)[0].value;
$("#slider").slider({
min: MinYear,
max: MaxYear,
step: 1,
// values: d3.extent(data.map(function(d){return d.Sales})),
slide: function (event, ui) {
var index = $(ui.handle).index();
YearSelected = ui.value;
for (var i = 0; i < YearIndex.length; i++) {
switch (true) {
case YearSelected == nested[i].key:
var SwitchData = nested.filter(x => x.key === nested[i].key)[0].value;
MySlider(SwitchData)
break;
}
}
d3.select("#slider-data")
.html(YearSelected)
}
});
var x = d3.scaleBand()
.domain(airlines.map(function (d) { return d.key }))
.rangeRound([0, width]).padding(0.4);
svg.append("g")
.attr("class", "x axis")
.transition().duration(100)
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).scale(x));
svg.selectAll("g.x")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.transition().duration(1250)
.call(d3.axisBottom(x).scale(x));
var y = d3.scaleLinear()
.domain([0, d3.max(airlines.map(function (d) { return d.value }))])
.range([height, 0]);
svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(y).scale(y));
svg.selectAll("g.y")
.transition().duration(2000)
.call(d3.axisLeft(y).scale(y).ticks(5));
// var rects = svg.append("path")
// .data([airlines]);
// // define the line
// var valueline = d3.line()
// .x(function(d) { return x(d.key); })
// .y(function(d) { return y(+d.value); })
// rects
// .attr("fill", "none")
// .attr("stroke", "navy")
// .attr("stroke-width", 1.5)
// .attr("d", valueline);
// var rects = svg.selectAll("rect")
// .data(airlines);
// var colorScale = d3.scaleOrdinal()
// .domain(airlines.map(function(d, i){return i}))
// .range(["#b3d1ff", "#80b3ff", "#4d94ff", "#0052cc", "#002966"])
// // Update old ones, already have x / width from before
// rects
// .enter()
// .append("rect")
// .style("fill", function(d){ return colorScale(d.key)})
// .attr("x", function(d) { return x(d.key); })
// .attr("y", function(d) { return y( +d.value); })
// .attr("width", x.bandwidth())
// .style("stroke", function(d, i){return colorScale(i)})
// .attr("height", function(d) { return height - y(+d.value); })
// .on("mousemove", function(d){
// tooltip
// .style("left", d3.event.pageX - 50 + "px")
// .style("top", d3.event.pageY - 70 + "px")
// .style("display", "inline-block")
// .html((d.key) + "
" + "$" + (d.value));
// })
// .on("mouseout", function(d){ tooltip.style("display", "none");});
$("#play-button")
.on("click", function () {
var button = $(this);
if (button.text() == "Play") {
button.text("Pause");
IntervalSecondDelay = $("#seconds").val();
inter = setInterval(function () {
MyTimer(airlines);
}, IntervalSecondDelay);
} else {
button.text("Play");
clearInterval(inter);
}
})
$("#reset-button")
.on("click", function () {
// YearSelected = MinYear;
data0 = nested.filter(x => x.key === nested[0].key)[0].value;
MySelectBox(data0);
})
});
//=========================================
// Timer Function
function MyTimer(data) {
i++;
let airlines2 = nested[i]
if (typeof (airlines2) != "undefined") {
let airlines = nested.filter(x => x.key === nested[i].key)[0].value
var colorScale = d3.scaleOrdinal()
.domain(data.map(function (d, i) { return i }))
.range(["#b3d1ff", "#80b3ff", "#4d94ff", "#0052cc", "#002966"])
// svg.select("g.legend")
// .data(airlines)
// .enter().append("g")
// .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; })
// .append("rect")
// .attr("width", 18)
// .attr("height", 18)
// .style("fill", function(d){ return colorScale(d.key)})
var ArrayOne = [];
Object.keys(data).forEach(function (key) {
ArrayOne.push(data[key].key);
})
d3.select("g").selectAll("text").remove();
legend
.data(airlines)
.append("text")
.attr("transform", "translate(630, 0)")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("font-family", "Arial,Helvetica Neue,Helvetica")
.style("font-size", "10px")
.attr("fill", "#484848")
.text(function (d) { return d.key })
d3.select("g").selectAll("circle").remove();
legend.append("circle")
.data(airlines)
.style("fill", "azure")
.attr("cx", 5)
.attr("cy", 5)
.attr("r", 6)
.attr("transform", "translate(635, 4)")
.transition().duration(LegendTransitionTime)
.style("fill", function (d) { return colorScale(d.key) });
d3.select(".OneClass")
.remove();
var one = d3.select("svg").append("svg")
.attr("class", "OneClass");
one
.append("text")
.attr("fill", "white")
//.attr("transform", "translate(745, 280)")
.attr("transform", "translate(699, 24)")
.text(nested[i].key)
.style("font-family", "Arial,Helvetica Neue,Helvetica")
.style("font-size", "10.5px")
.transition().duration(LegendTransitionTime)
.attr("fill", "#4d071f")
one
.append("circle")
.style("fill", "azure")
.attr("cx", 5)
.attr("cy", 5)
.attr("r", 6)
.attr("transform", "translate(680, 14)")
//.transition().duration(1000)
.style("fill", function (d) { return colorScale(d) });
// document.getElementById("sliderTwo").innerHTML = "Current Year " +
// ""+ nested[i].key +""
var x = d3.scaleBand()
.domain(airlines.map(function (d) { return d.key }))
.rangeRound([0, width]).padding(1.2);
svg.append("g")
.attr("class", "x axis")
.transition().duration(100)
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).scale(x));
svg.selectAll("g.x")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.transition().duration(2000)
.call(d3.axisBottom(x).scale(x));
var y = d3.scaleLinear()
.domain([0, d3.max(airlines.map(function (d) { return d.value }))])
.range([height, 0]);
svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(y).scale(y));
svg.selectAll("g.y")
.transition().duration(2000)
.call(d3.axisLeft(y).scale(y).ticks(5));
this.svg.selectAll(".PlayButtonLine").remove()
var rects = svg.append("path")
.attr("class", "PlayButtonLine")
.data([airlines]);
// define the line
var valueline = d3.line()
.x(function (d) { return x(d.key); })
.y(function (d) { return y(+d.value); })
rects
.style("fill", "none")
.style("stroke-width", "2px")
.style("stroke", colorScale)
.attr("d", valueline);
var data1 = ['red', 'blue', 'lightblue', 'grey', 'yellow'];
}
else if (typeof (airlines2) === "undefined") {
// document.getElementById("sliderTwo").innerHTML = "Current Number " + i +
// ""+ "End Of Series Reached" + new Date() + "";
clearInterval(inter);
$(document).ready(function () {
// Change text of input button
// $("#myInput").prop("value", "Input New Text");
// Change text of button element
$("#play-button").html("Play");
// Here We Set The Counter To Zero
i = 0;
});}}
function MySlider(data) {
var ArrayOne = [];
Object.keys(data).forEach(function (key) {
ArrayOne.push(data[key].key);
})
var colorScale = d3.scaleOrdinal()
.domain(data.map(function (d, i) { return i }))
.range(["#b3d1ff", "#80b3ff", "#4d94ff", "#0052cc", "#002966"])
d3.select("g").selectAll("text").remove();
legend
.data(data)
.append("text")
.attr("transform", "translate(630, 0)")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("font-family", "Arial,Helvetica Neue,Helvetica")
.style("font-size", "10px")
.attr("fill", "#484848")
.text(function (d) { return d.key })
d3.select("g").selectAll("circle").remove();
legend.append("circle")
.data(data)
.style("fill", "azure")
.attr("cx", 5)
.attr("cy", 5)
.attr("r", 6)
.attr("transform", "translate(635, 4)")
.transition().duration(LegendTransitionTime)
.style("fill", function (d) { return colorScale(d.key) });
d3.select(".OneClass")
.remove();
var one = d3.select("svg").append("svg")
.attr("class", "OneClass");
one
.append("text")
.attr("fill", "white")
//.attr("transform", "translate(745, 280)")
.attr("transform", "translate(699, 24)")
.text(YearSelected)
.style("font-family", "Arial,Helvetica Neue,Helvetica")
.style("font-size", "10.5px")
.transition().duration(1700)
.attr("fill", "#4d071f")
one
.append("circle")
.style("fill", "azure")
.attr("cx", 5)
.attr("cy", 5)
.attr("r", 6)
.attr("transform", "translate(680, 14)")
//.transition().duration(1000)
.style("fill", function (d) { return colorScale(d) });
var x = d3.scaleBand()
.domain(data.map(function (d) { return d.key }))
.rangeRound([0, width]).padding(0.4);
svg.append("g")
.attr("class", "x axis")
.transition().duration(LegendTransitionTime)
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).scale(x));
svg.selectAll("g.x")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.transition().duration(LegendTransitionTime)
.call(d3.axisBottom(x).scale(x));
var y = d3.scaleLinear()
.domain([0, d3.max(data.map(function (d) { return d.value }))])
.range([height, 0]);
svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(y).scale(y));
svg.selectAll("g.y")
.transition().duration(2000)
.call(d3.axisLeft(y).scale(y).ticks(5));
svg.selectAll("rect").remove();
var rects = svg.selectAll("rect")
.data(data);
rects
.enter()
.append("rect")
.on("mousemove", function (d) {
tooltip
.style("left", d3.event.pageX - 50 + "px")
.style("top", d3.event.pageY - 70 + "px")
.style("display", "inline-block")
.html((d.key) + "
" + "$" + (d.value))
})
.on("mouseout", function (d) { tooltip.style("display", "none"); })
// .classed("barThree", true)
.style("fill", function (d) { return colorScale(d.key) })
.style("stroke", "red")
.style("stroke-width", ".5px")
.attr("x", function (d) { return x(d.key); })
.attr("width", x.bandwidth())
.attr("y", function (d) {
return y(0)
})
.attr("height", 0)
.transition().duration(2500)
.attr("y", function (d) {
return y(+d.value);
})
.attr("height", function (d) {
return height - y(+d.value)
});}
// SELECT BOX
//================================================
function MySelectBox(airlines) {
var ArrayOne = [];
Object.keys(airlines).forEach(function (key) {
ArrayOne.push(airlines[key].key);
})
var colorScale = d3.scaleOrdinal()
.domain(airlines.map(function (d, i) { return i }))
.range(["#b3d1ff", "#80b3ff", "#4d94ff", "#0052cc", "#002966"])
d3.select("g").selectAll("text").remove();
legend
.data(ArrayOne)
.append("text")
.attr("transform", "translate(630, 0)")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("font-family", "Arial,Helvetica Neue,Helvetica")
.style("font-size", "10px")
.attr("fill", "#484848")
.text(function (d) { return d })
d3.select("g").selectAll("circle").remove();
legend.append("circle")
.data(ArrayOne)
.style("fill", "azure")
.attr("cx", 5)
.attr("cy", 5)
.attr("r", 6)
.attr("transform", "translate(635, 4)")
.transition().duration(1000)
.style("fill", function (d) { return colorScale(d) });
d3.select(".OneClass")
.remove();
var one = d3.select("svg").append("svg")
.attr("class", "OneClass");
one
.append("text")
.attr("fill", "white")
//.attr("transform", "translate(745, 280)")
.attr("transform", "translate(699, 24)")
.text(nested[selectedFruit].key)
.style("font-family", "Arial,Helvetica Neue,Helvetica")
.style("font-size", "10.5px")
.transition().duration(1700)
.attr("fill", "#4d071f")
one
.append("circle")
.style("fill", "azure")
.attr("cx", 5)
.attr("cy", 5)
.attr("r", 6)
.attr("transform", "translate(680, 14)")
//.transition().duration(1000)
.style("fill", function (d) { return colorScale(d) });
var x = d3.scaleBand()
.domain(airlines.map(function (d) { return d.key }))
.rangeRound([0, width]).padding(0.4);
svg.append("g")
.attr("class", "x axis")
.transition().duration(100)
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).scale(x));
svg.selectAll("g.x")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.transition().duration(2000)
.call(d3.axisBottom(x).scale(x));
var y = d3.scaleLinear()
.domain([0, d3.max(airlines.map(function (d) { return d.value }))])
.range([height, 0]);
svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(y).scale(y));
svg.selectAll("g.y")
.transition().duration(2000)
.call(d3.axisLeft(y).scale(y).ticks(5));
svg.selectAll("rect").remove();
var rects = svg.selectAll("rect")
.data(airlines);
rects
.enter()
.append("rect")
.on("mousemove", function (d) {
tooltip
.style("left", d3.event.pageX - 50 + "px")
.style("top", d3.event.pageY - 70 + "px")
.style("display", "inline-block")
.html((d.key) + "
" + "$" + (d.value))
})
.on("mouseout", function (d) { tooltip.style("display", "none"); })
// .classed("barThree", true)
.style("fill", function (d) { return colorScale(d.key) })
.style("stroke", "red")
.style("stroke-width", ".5px")
.attr("x", function (d) { return x(d.key); })
.attr("width", x.bandwidth())
.attr("y", function (d) {
return y(0)
})
.attr("height", 0)
.transition().duration(2500)
.attr("y", function (d) {
return y(+d.value);
})
.attr("height", function (d) {
return height - y(+d.value)
});
}