Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bootstrap + C3; Grid layout doesn't work on load #2474

Closed
chrismp opened this issue Sep 10, 2018 · 5 comments
Closed

Bootstrap + C3; Grid layout doesn't work on load #2474

chrismp opened this issue Sep 10, 2018 · 5 comments

Comments

@chrismp
Copy link

chrismp commented Sep 10, 2018

  • C3 version: 0.6.7
  • D3 version: 5
  • Browser: Firefox ESR
  • OS: Debian 9

I want to make a web page that has four rows of three donut charts each. I'm using Bootstrap with C3.js.

My code looks like this.

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">

	<title>U.S. presidential vote, 1972-2016, by race</title>

	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
	<link href="css/c3.min.css" rel="stylesheet">
	<style type="text/css">
		.c3-chart-arcs-title {
			font-size: 1.5rem;
		}
	</style>


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

	<script type="text/javascript">
		var dataDir = "vote-by-race";
		d3.csv(dataDir+"/white.csv").then(function(data){
			var row;
			data.forEach(function(d,i){
				if (i%3===0) {
					row = document.createElement("div");
					row.className = "row";
				}

				var col = document.createElement("div");
				col.className = "col-sm";

				var chartDiv = document.createElement("div");
				chartDiv.id = "chart"+i;

				col.appendChild(chartDiv);
				row.appendChild(col);
				document.getElementById("charts").appendChild(row);

				var chartDataObj = Object.assign({},d);
				delete chartDataObj["Year"];
				var chart = c3.generate({
					data: {
						json: chartDataObj,
						type: "donut",
						colors: {
							Democrat: "#2166ac",
							Republican: "#b2182b",
							Other: "#bbb"
						}
					},
					tooltip: {
						show: false
					},
					legend: {
						show: false
					},
					donut: {
						title: d["Year"],
						label: {
							format: function(value,ratio,id){
								return d3.format('.0%')(value/100);
							}
						}
					},
					bindto: '#'+chartDiv.id
				});
			});
		});
	</script>
</head>
<body>
	<div id="charts" class="container"></div>
</body>
</html>

My CSV...

Year,Democrat,Republican,Other
1972,32,66,2
1976,47,52,1
1980,35,56,9
1984,35,64,1
1988,40,59,1
1992,39,40,21
1996,43,46,11
2000,42,54,4
2004,41,58,1
2008,43,55,2
2012,39,59,2
2016,37,58,5

When I load the page in my browser, I see 12 donut charts in a single vertical column. But when I resize the browser window to its thinnest, then expand it again, I see four rows of three donut charts each.

How do I make the browser show four rows of three charts each when the charts are first loaded?

@kt3k
Copy link
Member

kt3k commented Sep 10, 2018

I guess that it happens because the first column occupies the whole width because it's the only column in a row when it's drawn.

How about preparing the container <div >s first in html like the below?

<div id="charts" class="container">
  <div class="row">
    <div class="col-sm"><div id="chart0"><div></div>
    <div class="col-sm"><div id="chart1"><div></div>
    <div class="col-sm"><div id="chart2"><div></div>
  </div>
  <div class="row">
    <div class="col-sm"><div id="chart3"><div></div>
    <div class="col-sm"><div id="chart4"><div></div>
    <div class="col-sm"><div id="chart5"><div></div>
  </div>
  <div class="row">
    <div class="col-sm"><div id="chart6"><div></div>
    <div class="col-sm"><div id="chart7"><div></div>
    <div class="col-sm"><div id="chart8"><div></div>
  </div>
  <div class="row">
    <div class="col-sm"><div id="chart9"><div></div>
    <div class="col-sm"><div id="chart10"><div></div>
    <div class="col-sm"><div id="chart11"><div></div>
  </div>
</div>

@chrismp
Copy link
Author

chrismp commented Sep 10, 2018

Here's my code now...

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">

	<title>U.S. presidential vote, 1972-2016, by race</title>

	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
	<link href="css/c3.min.css" rel="stylesheet">
	<style type="text/css">
		.c3-chart-arcs-title {
			font-size: 2.5rem;
		}

		.c3-chart-arc text {
			font-weight: bold;
			font-size: 1rem;
		}
	</style>


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

	<script type="text/javascript">
		var dataDir = "vote-by-race";
		d3.csv(dataDir+"/white.csv").then(function(data){
			data.forEach(function(d,i){
				var chartDataObj = Object.assign({},d);
				delete chartDataObj["Year"];
				var chart = c3.generate({
					data: {
						json: chartDataObj,
						type: "donut",
						colors: {
							Democrat: "#2166ac",
							Republican: "#b2182b",
							Other: "#bbb"
						}
					},
					tooltip: {
						show: false
					},
					legend: {
						show: false
					},
					donut: {
						title: d["Year"],
						label: {
							format: function(value,ratio,id){
								return d3.format('.0%')(value/100);
							}
						}
					},
					bindto: "#chart"+i
				});
			});
		});
	</script>
</head>
<body>
	<div id="charts" class="container">
		<div class="row">
			<div class="col-sm"><div id="chart0"><div></div>
			<div class="col-sm"><div id="chart1"><div></div>
			<div class="col-sm"><div id="chart2"><div></div>
		</div>
		<div class="row">
			<div class="col-sm"><div id="chart3"><div></div>
			<div class="col-sm"><div id="chart4"><div></div>
			<div class="col-sm"><div id="chart5"><div></div>
		</div>
		<div class="row">
			<div class="col-sm"><div id="chart6"><div></div>
			<div class="col-sm"><div id="chart7"><div></div>
			<div class="col-sm"><div id="chart8"><div></div>
		</div>
		<div class="row">
			<div class="col-sm"><div id="chart9"><div></div>
			<div class="col-sm"><div id="chart10"><div></div>
			<div class="col-sm"><div id="chart11"><div></div>
		</div>
	</div>
</body>
</html>

But now when I open the browser I see only the first donut chart. When I open the DOM inspector, #charts has only the first .row

@chrismp
Copy link
Author

chrismp commented Sep 10, 2018

Just noticed the typos in the HTML and corrected them.

	<div id="charts" class="container">
		<div class="row">
			<div class="col-sm"><div id="chart0"></div></div>
			<div class="col-sm"><div id="chart1"></div></div>
			<div class="col-sm"><div id="chart2"></div></div>
		</div>
		<div class="row">
			<div class="col-sm"><div id="chart3"></div></div>
			<div class="col-sm"><div id="chart4"></div></div>
			<div class="col-sm"><div id="chart5"></div></div>
		</div>
		<div class="row">
			<div class="col-sm"><div id="chart6"></div></div>
			<div class="col-sm"><div id="chart7"></div></div>
			<div class="col-sm"><div id="chart8"></div></div>
		</div>
		<div class="row">
			<div class="col-sm"><div id="chart9"></div></div>
			<div class="col-sm"><div id="chart10"></div></div>
			<div class="col-sm"><div id="chart11"></div></div>
		</div>
	</div>

Thanks for the tip. The charts show up in four rows of threes. But is there any way to accomplish this while drawing them? It's not absolutely necessary, but I prefer automating those divs since I prefer not to repeat myself ;)

chrismp pushed a commit to chrismp/chrismp.github.io that referenced this issue Sep 10, 2018
- Follow suggestion to try fixing white vote charts: c3js/c3#2474 (comment)
@kt3k
Copy link
Member

kt3k commented Sep 11, 2018

I think the point is the timing between creating container elements and drawing charts. You need to create all rows and columns before drawing any charts. How about the following?

	<script type="text/javascript">
		var dataDir = "vote-by-race";
		d3.csv(dataDir+"/white.csv").then(function(data){
			var row;
			// Creates container rows and columns
			data.forEach(function(d,i){
				if (i%3===0) {
					row = document.createElement("div");
					row.className = "row";
				}

				var col = document.createElement("div");
				col.className = "col-sm";

				var chartDiv = document.createElement("div");
				chartDiv.id = "chart"+i;

				col.appendChild(chartDiv);
				row.appendChild(col);
				document.getElementById("charts").appendChild(row);
			})

			// Draws charts
			data.forEach(function(d,i){
				var chartDataObj = Object.assign({},d);
				delete chartDataObj["Year"];
				var chart = c3.generate({
				    ...
				});
			});
		});
	</script>

	<div id="charts" class="container"></div>

@kt3k
Copy link
Member

kt3k commented Sep 19, 2018

Closing the issue because the rest of the problem doesn't seem belonging to c3.

@kt3k kt3k closed this as completed Sep 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants