Two identical D3 graphs on the same web page?

29 views
Skip to first unread message

Gregory Sloggett

unread,
Mar 13, 2018, 1:14:02 PM3/13/18
to d3-js
Hi,  

I'm trying to display two identical d3 graphs on the same web page (one which i'll later change but I just want to get two graphs on the same page). They both read from the same exact csv file, and display on a graph. I've got the graph working by itself alone and although i'm relatively new to d3 I have a firm understanding of the fundamentals.

My code is attached below, I'm basically attempting to display the two graphs, one under one navigation bar tab, and the other under another tab. 

Any help would be greatly appreciated and thanks in advance!

Greg

code -->

<div class="row">
<div class="col-sm-12">

<ul class="nav nav-tabs nav-justified">
<li class="active"><a data-toggle="tab" href="#kilometre">Kilometre Splits</a></li>
<li><a data-toggle="tab" href="#landmark">Landmark Splits</a></li>
</ul>
<br>
<div class="tab-content">
<div id="kilometre" class="tab-pane fade in active">
<h4>Kilometre Splits</h4>

<svg width="100%" height="500px"></svg>

<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

// SETUP
var svg = d3.select("svg"),
margin = { top: 20, right: 20, bottom: 30, left: 40 },
x = d3.scaleBand().padding(0.1),
y = d3.scaleLinear(),
theData = undefined;

var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

g.append("g")
.attr("class", "axis axis--x");

g.append("g")
.attr("class", "axis axis--y");

g.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Pace");

// DRAWING

function draw_chart() {

var bounds = svg.node().getBoundingClientRect(),
width = bounds.width - margin.left - margin.right,
height = bounds.height - margin.top - margin.bottom;

x.rangeRound([0, width]);
y.rangeRound([height, 0]);

g.select(".axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));

g.select(".axis--y")
.call(d3.axisLeft(y));

var bars = g.selectAll(".bar")
.data(theData);

{# var slider = chart.append("g")#}
{# .attr("class", "slider")#}
{# .attr("transform", "translate(" + margin.left + "," + (height + margin.bottom) + ")");#}
{# #}

// ENTER
bars.enter().append("rect")
.attr("class", "bar")
.attr("x", function (d) { return x(d.kilometre); })
.attr("y", function (d) { return y(d.pace); })
.attr("width", x.bandwidth())
.attr("height", function (d) { return height - y(d.pace); });

// UPDATE
bars.attr("x", function (d) { return x(d.kilometre); })
.attr("y", function (d) { return y(d.pace); })
.attr("width", x.bandwidth())
.attr("height", function (d) { return height - y(d.pace); });

// EXIT
bars.exit()
.remove();

}

// LOADING DATA

function loadData(csvFile) {

d3.csv(csvFile, function (d) {
d.pace = +d.pace;
d.kilometre = +d.kilometre;
return d;

}, function (error, data) {
if (error) throw error;

theData = data;

x.domain(theData.map(function (d) { return d.kilometre; }));
y.domain([0, d3.max(theData, function (d) { return d.pace; })+1]);

draw_chart();

});
}

// START!

window.addEventListener("resize", draw_chart);
loadData("/static/data.csv" + '?' + Math.floor(Math.random() * 1000));

</script>

</div>
<div id="landmark" class="tab-pane fade">
<h4>Landmark Splits</h4>

<svg width="100%" height="500px"></svg>

<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

// SETUP
var svg = d3.select("svg"),
margin = { top: 20, right: 20, bottom: 30, left: 40 },
x = d3.scaleBand().padding(0.1),
y = d3.scaleLinear(),
theData = undefined;

var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

g.append("g")
.attr("class", "axis axis--x");

g.append("g")
.attr("class", "axis axis--y");

g.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Pace");

// DRAWING

function draw_chart() {

var bounds = svg.node().getBoundingClientRect(),
width = bounds.width - margin.left - margin.right,
height = bounds.height - margin.top - margin.bottom;

x.rangeRound([0, width]);
y.rangeRound([height, 0]);

g.select(".axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));

g.select(".axis--y")
.call(d3.axisLeft(y));

var bars = g.selectAll(".bar")
.data(theData);

{# var slider = chart.append("g")#}
{# .attr("class", "slider")#}
{# .attr("transform", "translate(" + margin.left + "," + (height + margin.bottom) + ")");#}
{# #}

// ENTER
bars.enter().append("rect")
.attr("class", "bar")
.attr("x", function (d) { return x(d.kilometre); })
.attr("y", function (d) { return y(d.pace); })
.attr("width", x.bandwidth())
.attr("height", function (d) { return height - y(d.pace); });

// UPDATE
bars.attr("x", function (d) { return x(d.kilometre); })
.attr("y", function (d) { return y(d.pace); })
.attr("width", x.bandwidth())
.attr("height", function (d) { return height - y(d.pace); });

// EXIT
bars.exit()
.remove();

}

// LOADING DATA

function loadData(csvFile) {

d3.csv(csvFile, function (d) {
d.pace = +d.pace;
d.kilometre = +d.kilometre;
return d;

}, function (error, data) {
if (error) throw error;

theData = data;

x.domain(theData.map(function (d) { return d.kilometre; }));
y.domain([0, d3.max(theData, function (d) { return d.pace; })+1]);

draw_chart();

});
}

// START!

window.addEventListener("resize", draw_chart);
loadData("/static/data.csv" + '?' + Math.floor(Math.random() * 1000));

</script>

</div>
</div>
</div>
</div>

Frank Guerino

unread,
Mar 15, 2018, 11:12:06 AM3/15/18
to d3...@googlegroups.com
Hi Greg,

Take a look at these examples.  They all segment a page into separate divs and reuse the same chart, multiple times, with minor modifications...

Mirrored Stacked Bar Charts: http://bl.ocks.org/Guerino1/raw/2354192/ 

I hope they help,

Frank


--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ibrahim Tanyalcin

unread,
Mar 15, 2018, 12:30:33 PM3/15/18
to d3...@googlegroups.com
Greg,

One other solution is to create your own object instance that operates on the same csv or whatever dataset, then takes care of the displaying its own svg elements etc. If you are going to mutate the data make sure to make a recursive copy of the object/array. Like here:

Reply all
Reply to author
Forward
0 new messages