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

Add word clouds to my year archive pages #391

Closed
simonw opened this issue Jan 4, 2024 · 4 comments
Closed

Add word clouds to my year archive pages #391

simonw opened this issue Jan 4, 2024 · 4 comments

Comments

@simonw
Copy link
Owner

simonw commented Jan 4, 2024

https://simonwillison.net/2006/ is a bit dull looking:

CleanShot 2024-01-04 at 12 16 06@2x

I'm going to add word clouds generated by this dashboard: https://simonwillison.net/dashboard/tag-cloud-by-year/?year=2006

It has a JSON API already. They'll look like the one in this blog post: https://simonwillison.net/2023/Dec/31/ai-in-2023/#my-blog-2023

image

@simonw
Copy link
Owner Author

simonw commented Jan 4, 2024

Pasted code from Django SQL Dashboard into ChatGPT and got it do do most of the work: https://chat.openai.com/share/5bbde5a8-0c5b-4bfa-93db-2f83a0bc8846

End result:

// Function to inject a script into the page
function injectScript(src, integrity, crossorigin) {
  var script = document.createElement('script');
  script.src = src;
  script.integrity = integrity;
  script.crossOrigin = crossorigin;
  document.head.appendChild(script);
}

// Injecting the specified scripts
injectScript(
  "https://cdn.jsdelivr.net/npm/d3-cloud@1.2.5",
  "sha384-QdJK9M8QwqLqENe8Vd/mQIIk/BUQCC3BLh+kqB+UPKbKBsvOmcnmZTikm9prWMeO",
  "anonymous"
);
injectScript(
  "https://cdn.jsdelivr.net/npm/d3@6.7.0",
  "sha384-ma33ZEb8L5emtidZhYJFZNIFdht2E8f5wHQMKQGom0aIx9rRKm86XXCjGxOISpM9",
  "anonymous"
);


(function() {
  fetch('https://simonwillison.net/dashboard/tag-cloud-by-year.json?year=2010')
    .then(response => response.json())
    .then(data => {
      var wordcloudData = data.queries[0].rows;
      var minScore = Math.min(...wordcloudData.map(w => w.wordcloud_count));
      var maxScore = Math.max(...wordcloudData.map(w => w.wordcloud_count));
      var fontScale = d3.scaleLinear()
        .domain([minScore, maxScore])
        .range([20, 100]);

      function colors(s) {
        return s.match(/.{6}/g).map(function(x) {
          return "#" + x;
        });
      }
      var fill = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");

      function draw(words) {
        var svg = d3.select("#wordcloud-0").append("svg")
            .attr("width", layout.size()[0])
            .attr("height", layout.size()[1]);
        
        var g = svg.append("g")
            .attr("transform", "translate(" + layout.size()[0] / 2 + "," + layout.size()[1] / 2 + ")");
        
        var wordGroups = g.selectAll("g")
            .data(words)
            .enter().append("g")
            .attr("transform", function(d) {
              return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
            });

        wordGroups.append("a")
            .attr("xlink:href", function(d) { return "https://simonwillison.net/tags/" + d.text; })
            .attr("target", "_blank")
          .append("text")
            .style("font-size", function(d) { return d.size + "px"; })
            .style("font-family", "Impact")
            .style("fill", function(d, i) { return fill[i % fill.length]; })
            .attr("text-anchor", "middle")
            .text(function(d) { return d.text; });
      }

      var wordData = wordcloudData.map(function(d) {
        return {text: d.wordcloud_word, size: d.wordcloud_count};
      });
      var layout = d3.layout.cloud()
        .size([document.querySelector('#wordcloud-0').getBoundingClientRect().width, 500])
        .words(wordData)
        .rotate(function() { return (~~(Math.random() * 6) - 3) * 30; })
        .padding(5)
        .font("Impact")
        .fontSize(function(d) { return fontScale(d.size); })
        .on("end", draw);
      layout.start();
    })
    .catch(error => {
      console.error('Error fetching data:', error);
    });
})();

@simonw
Copy link
Owner Author

simonw commented Jan 4, 2024

Note that this feature only works if /dashboard/tag-cloud-by-year.json?year=2010 has been created.

@simonw
Copy link
Owner Author

simonw commented Jan 4, 2024

I could create that with a migration, but I'm feeling lazy so I won't bother.

@simonw
Copy link
Owner Author

simonw commented Jan 4, 2024

Tooted about this here: https://fedi.simonwillison.net/@simon/111699647075781977

@simonw simonw closed this as completed Jan 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant