Built with blockbuilder.org
xxxxxxxxxx
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css">
<style>
.chart-wrapper {
max-width: 950px;
min-width: 304px;
margin: 0 auto;
background-color: #FAF7F7;
}
.chart-wrapper .inner-wrapper {
position: relative;
padding-bottom: 50%;
width: 100%;
}
.chart-wrapper .outer-box {
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
.chart-wrapper .inner-box {
width: 100%;
height: 100%;
}
.chart-wrapper text {
font-family: sans-serif;
font-size: 11px;
}
.chart-wrapper p {
font-size: 16px;
margin-top:5px;
margin-bottom: 40px;
}
.chart-wrapper .axis path,
.chart-wrapper .axis line {
fill: none;
stroke: #1F1F2E;
stroke-opacity: 0.7;
shape-rendering: crispEdges;
}
.chart-wrapper .axis path {
stroke-width: 2px;
}
.chart-wrapper .line {
fill: none;
stroke: steelblue;
stroke-width: 5px;
}
.chart-wrapper .legend {
min-width: 200px;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
font-size: 16px;
padding: 10px 40px;
}
.chart-wrapper .legend > div {
margin: 0px 25px 10px 0px;
flex-grow: 0;
}
.chart-wrapper .legend p {
display:inline;
font-size: 0.8em;
font-family: sans-serif;
font-weight: 600;
}
.chart-wrapper .legend .series-marker {
height: 1em;
width: 1em;
border-radius: 35%;
background-color: crimson;
display: inline-block;
margin-right: 4px;
margin-bottom: -0.16rem;
}
.chart-wrapper .overlay {
fill: none;
pointer-events: all;
}
.chart-wrapper .focus circle {
fill: crimson;
stroke: crimson;
stroke-width: 2px;
fill-opacity: 15%;
}
.chart-wrapper .focus rect {
fill: lightblue;
opacity: 0.4;
border-radius: 2px;
}
.chart-wrapper .focus.line {
stroke: steelblue;
stroke-dasharray: 2,5;
stroke-width: 2;
opacity: 0.5;
}
@media (max-width:500px){
.chart-wrapper .line {stroke-width: 3px;}
.chart-wrapper .legend {font-size: 14px;}
}
</style>
<script src="https://d3js.org/d3.v3.js" charset="utf-8"></script>
<!--<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>-->
</head>
<body>
<div class="chart-wrapper" id="chart-line1"></div>
<script type="text/javascript">
d3.csv('https://gist.githubusercontent.com/rramvil/1c81782ddabe25064cd88dab69b1f5a0/raw/ae52dd4c9922b995d8b5dbe3498aad7ae65b561d/prueba', function(error, data) {
data.forEach(function (d) {
d.year = +d.year;
d.variableA = +d.variableA;
d.variableB = +d.variableB;
d.variableC = +d.variableC;
d.variableD = +d.variableD;
});
var chart = makeLineChart(data, 'year', {
'Variable A': {column: 'variableA'},
'Variable B': {column: 'variableB'},
'Variable C': {column: 'variableC'},
'Variable D': {column: 'variableD'}
}, {xAxis: 'Years', yAxis: 'Amount'});
chart.bind("#chart-line1");
chart.render();
});
</script>
<script charset="utf-8">
function makeLineChart(dataset, xName, yObjs, axisLables) {
var chartObj = {};
var color = d3.scale.category10();
chartObj.xAxisLable = axisLables.xAxis;
chartObj.yAxisLable = axisLables.yAxis;
/*
yObjsects format:
{y1:{column:'',name:'name',color:'color'},y2}
*/
chartObj.data = dataset;
chartObj.margin = {top: 15, right: 60, bottom: 30, left: 50};
chartObj.width = 650 - chartObj.margin.left - chartObj.margin.right;
chartObj.height = 480 - chartObj.margin.top - chartObj.margin.bottom;
// So we can pass the x and y as strings when creating the function
chartObj.xFunct = function(d){return d[xName]};
// For each yObjs argument, create a yFunction
function getYFn(column) {
return function (d) {
return d[column];
};
}
// Object instead of array
chartObj.yFuncts = [];
for (var y in yObjs) {
yObjs[y].name = y;
yObjs[y].yFunct = getYFn(yObjs[y].column); //Need this list for the ymax function
chartObj.yFuncts.push(yObjs[y].yFunct);
}
//Formatter functions for the axes
chartObj.formatAsNumber = d3.format(".0f");
chartObj.formatAsDecimal = d3.format(".2f");
chartObj.formatAsCurrency = d3.format("$.2f");
chartObj.formatAsFloat = function (d) {
if (d % 1 !== 0) {
return d3.format(".2f")(d);
} else {
return d3.format(".0f")(d);
}
};
chartObj.xFormatter = chartObj.formatAsNumber;
chartObj.yFormatter = chartObj.formatAsFloat;
chartObj.bisectYear = d3.bisector(chartObj.xFunct).left; //< Can be overridden in definition
//Create scale functions
chartObj.xScale = d3.scale.linear().range([0, chartObj.width]).domain(d3.extent(chartObj.data, chartObj.xFunct)); //< Can be overridden in definition
// Get the max of every yFunct
chartObj.max = function (fn) {
return d3.max(chartObj.data, fn);
};
chartObj.yScale = d3.scale.linear().range([chartObj.height, 0]).domain([0, d3.max(chartObj.yFuncts.map(chartObj.max))]);
chartObj.formatAsYear = d3.format("");
//Create axis
chartObj.xAxis = d3.svg.axis().scale(chartObj.xScale).orient("bottom").tickFormat(chartObj.xFormatter); //< Can be overridden in definition
chartObj.yAxis = d3.svg.axis().scale(chartObj.yScale).orient("left").tickFormat(chartObj.yFormatter); //< Can be overridden in definition
// Build line building functions
function getYScaleFn(yObj) {
return function (d) {
return chartObj.yScale(yObjs[yObj].yFunct(d));
};
}
for (var yObj in yObjs) {
yObjs[yObj].line = d3.svg.line().interpolate("cardinal").x(function (d) {
return chartObj.xScale(chartObj.xFunct(d));
}).y(getYScaleFn(yObj));
}
chartObj.svg;
// Change chart size according to window size
chartObj.update_svg_size = function () {
chartObj.width = parseInt(chartObj.chartDiv.style("width"), 10) - (chartObj.margin.left + chartObj.margin.right);
chartObj.height = parseInt(chartObj.chartDiv.style("height"), 10) - (chartObj.margin.top + chartObj.margin.bottom);
/* Update the range of the scale with new width/height */
chartObj.xScale.range([0, chartObj.width]);
chartObj.yScale.range([chartObj.height, 0]);
if (!chartObj.svg) {return false;}
/* Else Update the axis with the new scale */
chartObj.svg.select('.x.axis').attr("transform", "translate(0," + chartObj.height + ")").call(chartObj.xAxis);
chartObj.svg.select('.x.axis .label').attr("x", chartObj.width / 2);
chartObj.svg.select('.y.axis').call(chartObj.yAxis);
chartObj.svg.select('.y.axis .label').attr("x", -chartObj.height / 2);
/* Force D3 to recalculate and update the line */
for (var y in yObjs) {
yObjs[y].path.attr("d", yObjs[y].line);
}
d3.selectAll(".focus.line").attr("y2", chartObj.height);
chartObj.chartDiv.select('svg').attr("width", chartObj.width + (chartObj.margin.left + chartObj.margin.right)).attr("height", chartObj.height + (chartObj.margin.top + chartObj.margin.bottom));
chartObj.svg.select(".overlay").attr("width", chartObj.width).attr("height", chartObj.height);
return chartObj;
};
chartObj.bind = function (selector) {
chartObj.mainDiv = d3.select(selector);
// Add all the divs to make it centered and responsive
chartObj.mainDiv.append("div").attr("class", "inner-wrapper").append("div").attr("class", "outer-box").append("div").attr("class", "inner-box");
chartSelector = selector + " .inner-box";
chartObj.chartDiv = d3.select(chartSelector);
d3.select(window).on('resize.' + chartSelector, chartObj.update_svg_size);
chartObj.update_svg_size();
return chartObj;
};
// Render the chart
chartObj.render = function () {
//Create SVG element
chartObj.svg = chartObj.chartDiv.append("svg").attr("class", "chart-area").attr("width", chartObj.width + (chartObj.margin.left + chartObj.margin.right)).attr("height", chartObj.height + (chartObj.margin.top + chartObj.margin.bottom)).append("g").attr("transform", "translate(" + chartObj.margin.left + "," + chartObj.margin.top + ")");
// Draw Lines
for (var y in yObjs) {
yObjs[y].path = chartObj.svg.append("path").datum(chartObj.data).attr("class", "line").attr("d", yObjs[y].line).style("stroke", color(y)).attr("data-series", y).on("mouseover", function () {
focus.style("display", null);
}).on("mouseout", function () {
focus.transition().delay(700).style("display", "none");
}).on("mousemove", mousemove);
}
// Draw Axis
chartObj.svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + chartObj.height + ")").call(chartObj.xAxis).append("text").attr("class", "label").attr("x", chartObj.width / 2).attr("y", 30).style("text-anchor", "middle").text(chartObj.xAxisLable);
chartObj.svg.append("g").attr("class", "y axis").call(chartObj.yAxis).append("text").attr("class", "label").attr("transform", "rotate(-90)").attr("y", -42).attr("x", -chartObj.height / 2).attr("dy", ".71em").style("text-anchor", "middle").text(chartObj.yAxisLable);
//Draw tooltips
var focus = chartObj.svg.append("g").attr("class", "focus").style("display", "none");
for (var y in yObjs) {
yObjs[y].tooltip = focus.append("g");
yObjs[y].tooltip.append("circle").attr("r", 5);
yObjs[y].tooltip.append("rect").attr("x", 8).attr("y","-5").attr("width",22).attr("height",'0.75em');
yObjs[y].tooltip.append("text").attr("x", 9).attr("dy", ".35em");
}
// Year label
focus.append("text").attr("class", "focus year").attr("x", 9).attr("y", 7);
// Focus line
focus.append("line").attr("class", "focus line").attr("y1", 0).attr("y2", chartObj.height);
//Draw legend
var legend = chartObj.mainDiv.append('div').attr("class", "legend");
for (var y in yObjs) {
series = legend.append('div');
series.append('div').attr("class", "series-marker").style("background-color", color(y));
series.append('p').text(y);
yObjs[y].legend = series;
}
// Overlay to capture hover
chartObj.svg.append("rect").attr("class", "overlay").attr("width", chartObj.width).attr("height", chartObj.height).on("mouseover", function () {
focus.style("display", null);
}).on("mouseout", function () {
focus.style("display", "none");
}).on("mousemove", mousemove);
return chartObj;
function mousemove() {
var x0 = chartObj.xScale.invert(d3.mouse(this)[0]), i = chartObj.bisectYear(dataset, x0, 1), d0 = chartObj.data[i - 1], d1 = chartObj.data[i];
try {
var d = x0 - chartObj.xFunct(d0) > chartObj.xFunct(d1) - x0 ? d1 : d0;
} catch (e) { return;}
minY = chartObj.height;
for (var y in yObjs) {
yObjs[y].tooltip.attr("transform", "translate(" + chartObj.xScale(chartObj.xFunct(d)) + "," + chartObj.yScale(yObjs[y].yFunct(d)) + ")");
yObjs[y].tooltip.select("text").text(chartObj.yFormatter(yObjs[y].yFunct(d)));
minY = Math.min(minY, chartObj.yScale(yObjs[y].yFunct(d)));
}
focus.select(".focus.line").attr("transform", "translate(" + chartObj.xScale(chartObj.xFunct(d)) + ")").attr("y1", minY);
focus.select(".focus.year").text("Year: " + chartObj.xFormatter(chartObj.xFunct(d)));
}
};
return chartObj;
}
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.js to a secure url
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.js
https://d3js.org/d3.v3.min.js