Skip to content

Instantly share code, notes, and snippets.

@denisemauldin
Created April 26, 2018 01:36
Show Gist options
  • Save denisemauldin/3a62162d2a63d1aeea7ec22a95dbc1f4 to your computer and use it in GitHub Desktop.
Save denisemauldin/3a62162d2a63d1aeea7ec22a95dbc1f4 to your computer and use it in GitHub Desktop.
This a a line chart for Microwave Components Frequency Response
license: gpl-3.0

This line chart has lines and circles that are filled dots. This example demonstrates how to use selection.each to create a context to access parent and child data simultaneously and it is used to give the circles (child) the right color that is from the lines (parent).

forked from JerryWiltz's block: This a a line chart for Microwave Components Frequency Response

<!DOCTYPE html>
<svg id="canvas" width="500" height="300"></svg>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var myFilt = [
[ 40, 20, 30, 50], //['Freq', 'Insertion Loss', 'Return Loss', 'Noise Figure'],
[ 80, 22, 40, 55],
[120, 80, 90, 60],
[160, 100, 105, 65],
[200, 120, 130, 70]
];
var myFilterInputObject = {
inputTable : myFilt,
canvasId : '#canvas',
xMin : 0, xMax : 10, yMin : -100, yMax : 0,
xAxisTitle : 'Frequency, GHz', yAxisTitle : 'dB'
}
function scatterPlot (inputObject) {
var inputTable = inputObject.inputTable;
var canvasID = inputObject.canvasId;
var xMin = inputObject.xMin, xMax = inputObject.xMax, yMin = inputObject.yMin, yMax = inputObject.yMax;
var k = 0;
var p = 0;
var tsv = '';
inputTable.forEach( (element) => {
tsv += element.join('\t') + '\n';
});
//use d3 to turn tsv data into d3 data
var data = d3.tsvParse(tsv);
//change data type from string to float, for arbitrary sized/named table
data.forEach( d => {
for (k = 0; k < data.columns.length; k++){
d[data.columns[k]] = +d[data.columns[k]]
};
});
//change the data to nestedData
var nestedData = data.columns.slice(1).map(function(yName) {// this will return an array of objects
return {
yName: yName, // this is the rf dB plot
yValues: data.map(function(d) { // this will return an inner Array of objects
return {xValue: d[data.columns[0]], // this is the rf frequency
yValue: d[yName]}; // this is the dB value
})
};
});
var xExtent = (function () {//creates a one dimensional array
var temp = []
for (k = 0; k < data.length; k++) {
temp.push(nestedData[0].yValues[k].xValue);
}
return temp;
})();
var yExtent = (function () {//creates a one dimensional array
var temp = []
for (k = 0; k < data.length; k++) {
temp.push(nestedData[0].yValues[k].yValue);
}
return temp;
})();
var svg = (function () {//creates a one dimensional array
var temp = []
for (k = 0; k < nestedData.length; k++){
for (p = 0; p < data.length; p++) {
temp.push(nestedData[k].yValues[p].yValue);
}
}
return temp;
})()
//set up the plot area
var canvasRect = d3.select(canvasID).node().getBoundingClientRect();
var outerWidth = canvasRect.width
var outerHeight = canvasRect.height
var margin = { left: 70, top: 20, right: 20, bottom: 60 };
var innerWidth = outerWidth - margin.left - margin.right;
var innerHeight = outerHeight - margin.top - margin.bottom;
var x = d3.scaleLinear().domain(d3.extent(xExtent)).range([0, innerWidth]);
var y = d3.scaleLinear().domain(d3.extent(yExtent)).range([innerHeight, 0]);
var svg = d3.select(canvasID).append("svg")
.attr("width", outerWidth)
.attr("height", outerHeight);
var rect = svg.append('rect')
.attr("width", outerWidth)
.attr("height", outerHeight)
.attr('fill', 'none')
.attr('stroke', 'black')
.attr('stroke-width', '1px');
var xAxisTitle = inputObject.xAxisTitle;
var xAxisTitleOffset = 48;
var yAxisTitle = inputObject.yAxisTitle;
var yAxisTitleOffset = 40;
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//append the x axis onto g
g.append('g')
.attr('class', 'xAxis')
.style('font-size', '12')
.attr('transform', 'translate(0,' + innerHeight + ')')
.call(d3.axisBottom(x))
.append('text')
.attr("fill", "#000")
.style("text-anchor", "middle")
.attr("transform", "translate(" + (innerWidth / 2) + "," + xAxisTitleOffset + ")")
.style('font-size', '20')
.text(xAxisTitle);
//append the x axis grid onto g
g.append('g')
.attr("class", "xGrid")
.attr('transform', 'translate(0,' + innerHeight + ')')
.call(d3.axisBottom(x).tickSize(-innerHeight).tickFormat(""));
d3.select('g').select('g.xGrid').selectAll('g').select('line')
.attr('stroke', 'gray').attr('stroke-dasharray', '3, 3');
//append the y axis onto g
g.append('g')
.attr('class', 'yAxis')
.style('font-size', '12')
.call(d3.axisLeft(y))
.append('text')
.attr("fill", "#000")
.style("text-anchor", "middle")
.attr("transform", "translate(-" + yAxisTitleOffset + "," + (innerHeight / 2) + ") rotate(-90)")
.style('font-size', '20')
.text(yAxisTitle);
//append the x axis grid onto g
g.append('g')
.attr("class", "yGrid")
.call(d3.axisLeft(y).tickSize(-innerWidth).tickFormat(""));
d3.select('g').select('g.yGrid').selectAll('g').select('line')
.attr('stroke', 'gray').attr('stroke-dasharray', '3, 3');
function plotColor (label) {return d3.schemeCategory10[data.columns.slice(1).indexOf(label)];};
var plotGroups = g.selectAll('g.newPlot')
.data(nestedData)
.enter()
.append('g')
.attr('class', 'newPlot')
.each( function (d) {
d3.select(this).selectAll('circle')
.data(d => d.yValues)
.enter()
.append('circle')
.attr('cx', d => x(d.xValue))
.attr('cy', d => y(d.yValue))
.attr('r', 2)
.style("stroke", plotColor(d.yName)).style('fill', plotColor(d.yName)).style('stroke-width','2')
var line = d3.line()
.x(d => x(d.xValue))
.y(d => y(d.yValue));
d3.select(this).append("path")
.attr('d', d => line(d.yValues))
.style("stroke", plotColor(d.yName)).style('fill', 'none')
d3.select(this).append("text")
.attr("transform", function(d) { return "translate(" + x(d.yValues[d.yValues.length-2].xValue) + "," + y(d.yValues[d.yValues.length-2].yValue) + ")"; })
.attr("x", 3)
.attr("dy", "0.35em")
.style("font", "10px sans-serif")
.text(function(d) { return d.yName; });
})//end each
};
scatterPlot(myFilterInputObject);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment