Oliver Eyton-Williams ee1e8abd87
feat(curriculum): restore seed + solution to Chinese (#40683)
* feat(tools): add seed/solution restore script

* chore(curriculum): remove empty sections' markers

* chore(curriculum): add seed + solution to Chinese

* chore: remove old formatter

* fix: update getChallenges

parse translated challenges separately, without reference to the source

* chore(curriculum): add dashedName to English

* chore(curriculum): add dashedName to Chinese

* refactor: remove unused challenge property 'name'

* fix: relax dashedName requirement

* fix: stray tag

Remove stray `pre` tag from challenge file.

Signed-off-by: nhcarrigan <nhcarrigan@gmail.com>

Co-authored-by: nhcarrigan <nhcarrigan@gmail.com>
2021-01-12 19:31:00 -07:00

11 KiB

id, title, challengeType, dashedName
id title challengeType dashedName
5d8a4cfbe6b6180ed9a1ca58 Part 121 0 part-121

--description--

Add the enter and append functions to the selection. Pass the string tr to the append function to add three table row elements. These elements will be for displaying each platform's name.

--hints--

test-text

assert($('.dashboard div table tbody tr').length === 3);

--seed--

--before-user-code--

<!DOCTYPE html>
<html>
  <head>
    <title>D3 Dashboard</title>
    <style>
      body {
        background-color: #ccc;
        padding: 100px 10px;
      }

      .dashboard {
        width: 980px;
        height: 500px;
        background-color: white;
        box-shadow: 5px 5px 5px 5px #888;
        margin: auto;
        display: flex;
        align-items: center;
      }
    </style>
  </head>

  <body>
    <div class="dashboard"></div>
  </body>
</html>

--seed-contents--

<script>
  const data = [ 
    { year: 2012, followers: { twitter: 2594, tumblr:  401, instagram:   83 }},
    { year: 2013, followers: { twitter: 3049, tumblr:  440, instagram:  192 }},
    { year: 2014, followers: { twitter: 3511, tumblr:  415, instagram:  511 }},
    { year: 2015, followers: { twitter: 3619, tumblr:  492, instagram: 1014 }},
    { year: 2016, followers: { twitter: 4046, tumblr:  543, instagram: 2066 }},
    { year: 2017, followers: { twitter: 3991, tumblr:  701, instagram: 3032 }},
    { year: 2018, followers: { twitter: 3512, tumblr: 1522, instagram: 4512 }},
    { year: 2019, followers: { twitter: 3274, tumblr: 1989, instagram: 4715 }},
    { year: 2020, followers: { twitter: 2845, tumblr: 2040, instagram: 4801 }}
  ];
</script>
<script>
  const svgMargin = 70,
    svgWidth = 700,
    svgHeight = 500,
    twitterColor = '#7cd9d1',
    tumblrColor = '#f6dd71',
    instagramColor = '#fd9b98';

  const lineGraph = d3.select('.dashboard')
    .append('svg')
    .attr('width', svgWidth)
    .attr('height', svgHeight);

  const yScale = d3.scaleLinear()
    .domain([0, 5000])
    .range([svgHeight - svgMargin, svgMargin]);

  const xScale = d3.scaleLinear()
    .domain([2012, 2020])
    .range([svgMargin, svgWidth - svgMargin]);

  const yAxis = d3.axisLeft(yScale)
    .ticks(6, '~s');

  const xAxis = d3.axisBottom(xScale)
    .tickFormat(d3.format(''))
    .tickPadding(10);

  lineGraph.append('g')
    .call(yAxis)
    .attr('transform', `translate(${svgMargin}, 0)`)
    .style('font', '10px verdana');

  lineGraph.append('g')
    .call(xAxis)
    .attr('transform', `translate(0, ${svgHeight - svgMargin})`)
    .selectAll('text')
    .style('transform', 'translate(-12px, 0) rotate(-50deg)')
    .style('text-anchor', 'end')
    .style('cursor', 'pointer')
    .style('font', '10px verdana')

  const twitterLine = d3.line()
    .x(d => xScale(d.year))
    .y(d => yScale(d.followers.twitter));

  lineGraph.append('path')
    .attr('d', twitterLine(data))
    .attr('stroke', twitterColor)
    .attr('stroke-width', 3)
    .attr('fill', 'transparent');

  const tumblrLine = d3.line()
    .x(d => xScale(d.year))
    .y(d => yScale(d.followers.tumblr));

  lineGraph.append('path')
    .attr('d', tumblrLine(data))
    .attr('stroke', tumblrColor)
    .attr('stroke-width', 3)
    .attr('fill', 'transparent');

  const instagramLine = d3.line()
    .x(d => xScale(d.year))
    .y(d => yScale(d.followers.instagram));

  lineGraph.append('path')
    .attr('d', instagramLine(data))
    .attr('stroke', instagramColor)
    .attr('stroke-width', 3)
    .attr('fill', 'transparent');
    
  lineGraph.selectAll('twitter-circles')
    .data(data)
    .enter()
    .append('circle')
    .attr('cx', d => xScale(d.year))
    .attr('cy', d => yScale(d.followers.twitter))
    .attr('r', 6)
    .attr('fill', 'white')
    .attr('stroke', twitterColor)
    .style('cursor', 'pointer')

  lineGraph.selectAll('tumblr-circles')
    .data(data)
    .enter()
    .append('circle')
    .attr('cx', d => xScale(d.year))
    .attr('cy', d => yScale(d.followers.tumblr))
    .attr('r', 6)
    .attr('fill', 'white')
    .attr('stroke', tumblrColor)
    .style('cursor', 'pointer')

  lineGraph.selectAll('instagram-circles')
    .data(data)
    .enter()
    .append('circle')
    .attr('cx', d => xScale(d.year))
    .attr('cy', d => yScale(d.followers.instagram))
    .attr('r', 6)
    .attr('fill', 'white')
    .attr('stroke', instagramColor)
    .style('cursor', 'pointer')

  const rightDashboard = d3.select('.dashboard')
    .append('div');

  const pieGraph = rightDashboard.append('svg')
    .attr('width', 200)
    .attr('height', 200)

  const pieArc = d3.arc()
    .outerRadius(100)
    .innerRadius(0);

  const pieColors = d3.scaleOrdinal()  
    .domain(data[8].followers)
    .range([twitterColor, tumblrColor, instagramColor]);

  const pie = d3.pie()
    .value(d => d.value);
    
  const pieGraphData = pieGraph.selectAll('pieSlices')
    .data(pie(d3.entries(data[8].followers)))
    .enter()
    .append('g')
    .attr('transform', 'translate(100, 100)');

  pieGraphData.append('path')
    .attr('d', pieArc)
    .attr('fill', d => pieColors(d.data.key))
    .attr('stroke', 'white')
    .attr('stroke-width', 2);

  pieGraphData.append('text')
    .text(d => {
      const values = d3.values(data[8].followers);
      const sum = d3.sum(values);
      const percent = d.data.value/sum;
      return `${ Math.round(percent*100) }%`;
    })
    .attr('transform', d => `translate(${pieArc.centroid(d)})`)
    .style('text-anchor', 'middle')
    .style('font', '10px verdana');

  const legend = rightDashboard.append('table')
    .attr('width', 200)
    .attr('height', 120)
    .style('font', '12px verdana')

  const legendTitle = legend.append('thead')
    .append('tr')
    .append('th')
    .text('2020 followers')
    .attr('colspan', 3)

  const legendRows = legend.append('tbody')
    .selectAll('tr')
    .data(d3.entries(data[8].followers))



</script>

--solutions--

<script>
  const data = [ 
    { year: 2012, followers: { twitter: 2594, tumblr:  401, instagram:   83 }},
    { year: 2013, followers: { twitter: 3049, tumblr:  440, instagram:  192 }},
    { year: 2014, followers: { twitter: 3511, tumblr:  415, instagram:  511 }},
    { year: 2015, followers: { twitter: 3619, tumblr:  492, instagram: 1014 }},
    { year: 2016, followers: { twitter: 4046, tumblr:  543, instagram: 2066 }},
    { year: 2017, followers: { twitter: 3991, tumblr:  701, instagram: 3032 }},
    { year: 2018, followers: { twitter: 3512, tumblr: 1522, instagram: 4512 }},
    { year: 2019, followers: { twitter: 3274, tumblr: 1989, instagram: 4715 }},
    { year: 2020, followers: { twitter: 2845, tumblr: 2040, instagram: 4801 }}
  ];
</script>
<script>
  const svgMargin = 70,
    svgWidth = 700,
    svgHeight = 500,
    twitterColor = '#7cd9d1',
    tumblrColor = '#f6dd71',
    instagramColor = '#fd9b98';

  const lineGraph = d3.select('.dashboard')
    .append('svg')
    .attr('width', svgWidth)
    .attr('height', svgHeight);

  const yScale = d3.scaleLinear()
    .domain([0, 5000])
    .range([svgHeight - svgMargin, svgMargin]);

  const xScale = d3.scaleLinear()
    .domain([2012, 2020])
    .range([svgMargin, svgWidth - svgMargin]);

  const yAxis = d3.axisLeft(yScale)
    .ticks(6, '~s');

  const xAxis = d3.axisBottom(xScale)
    .tickFormat(d3.format(''))
    .tickPadding(10);

  lineGraph.append('g')
    .call(yAxis)
    .attr('transform', `translate(${svgMargin}, 0)`)
    .style('font', '10px verdana');

  lineGraph.append('g')
    .call(xAxis)
    .attr('transform', `translate(0, ${svgHeight - svgMargin})`)
    .selectAll('text')
    .style('transform', 'translate(-12px, 0) rotate(-50deg)')
    .style('text-anchor', 'end')
    .style('cursor', 'pointer')
    .style('font', '10px verdana')

  const twitterLine = d3.line()
    .x(d => xScale(d.year))
    .y(d => yScale(d.followers.twitter));

  lineGraph.append('path')
    .attr('d', twitterLine(data))
    .attr('stroke', twitterColor)
    .attr('stroke-width', 3)
    .attr('fill', 'transparent');

  const tumblrLine = d3.line()
    .x(d => xScale(d.year))
    .y(d => yScale(d.followers.tumblr));

  lineGraph.append('path')
    .attr('d', tumblrLine(data))
    .attr('stroke', tumblrColor)
    .attr('stroke-width', 3)
    .attr('fill', 'transparent');

  const instagramLine = d3.line()
    .x(d => xScale(d.year))
    .y(d => yScale(d.followers.instagram));

  lineGraph.append('path')
    .attr('d', instagramLine(data))
    .attr('stroke', instagramColor)
    .attr('stroke-width', 3)
    .attr('fill', 'transparent');
    
  lineGraph.selectAll('twitter-circles')
    .data(data)
    .enter()
    .append('circle')
    .attr('cx', d => xScale(d.year))
    .attr('cy', d => yScale(d.followers.twitter))
    .attr('r', 6)
    .attr('fill', 'white')
    .attr('stroke', twitterColor)
    .style('cursor', 'pointer')

  lineGraph.selectAll('tumblr-circles')
    .data(data)
    .enter()
    .append('circle')
    .attr('cx', d => xScale(d.year))
    .attr('cy', d => yScale(d.followers.tumblr))
    .attr('r', 6)
    .attr('fill', 'white')
    .attr('stroke', tumblrColor)
    .style('cursor', 'pointer')

  lineGraph.selectAll('instagram-circles')
    .data(data)
    .enter()
    .append('circle')
    .attr('cx', d => xScale(d.year))
    .attr('cy', d => yScale(d.followers.instagram))
    .attr('r', 6)
    .attr('fill', 'white')
    .attr('stroke', instagramColor)
    .style('cursor', 'pointer')

  const rightDashboard = d3.select('.dashboard')
    .append('div');

  const pieGraph = rightDashboard.append('svg')
    .attr('width', 200)
    .attr('height', 200)

  const pieArc = d3.arc()
    .outerRadius(100)
    .innerRadius(0);

  const pieColors = d3.scaleOrdinal()  
    .domain(data[8].followers)
    .range([twitterColor, tumblrColor, instagramColor]);

  const pie = d3.pie()
    .value(d => d.value);
    
  const pieGraphData = pieGraph.selectAll('pieSlices')
    .data(pie(d3.entries(data[8].followers)))
    .enter()
    .append('g')
    .attr('transform', 'translate(100, 100)');

  pieGraphData.append('path')
    .attr('d', pieArc)
    .attr('fill', d => pieColors(d.data.key))
    .attr('stroke', 'white')
    .attr('stroke-width', 2);

  pieGraphData.append('text')
    .text(d => {
      const values = d3.values(data[8].followers);
      const sum = d3.sum(values);
      const percent = d.data.value/sum;
      return `${ Math.round(percent*100) }%`;
    })
    .attr('transform', d => `translate(${pieArc.centroid(d)})`)
    .style('text-anchor', 'middle')
    .style('font', '10px verdana');

  const legend = rightDashboard.append('table')
    .attr('width', 200)
    .attr('height', 120)
    .style('font', '12px verdana')

  const legendTitle = legend.append('thead')
    .append('tr')
    .append('th')
    .text('2020 followers')
    .attr('colspan', 3)

  const legendRows = legend.append('tbody')
    .selectAll('tr')
    .data(d3.entries(data[8].followers))
    .enter()
    .append('tr');




</script>