import React, { useState, useEffect } from 'react'; import * as d3 from 'd3'; import { GoogleLogin } from 'react-google-login'; const ChannelGrowthChart = () => { // Define the YouTube API client ID const YOUTUBE_API_CLIENT_ID = 'AIzaSyBmSAKk546uXKEB3VKXmzhMqtvIclBvkwM'; // Define the YouTube channel ID for which you want to visualize the channel growth through video success const CHANNEL_ID = 'UCrY4rBbh2eU6GQXVNsKoW7w'; // Define the API endpoint for retrieving the video data const API_ENDPOINT = `https://www.googleapis.com/youtube/v3/search?key=${YOUTUBE_API_CLIENT_ID}&channelId=${CHANNEL_ID}&part=snippet,id&order=viewCount&maxResults=50`; // Define the D3.js chart dimensions const CHART_WIDTH = 600; const CHART_HEIGHT = 400; // Define the state variables for the video data and any error messages const [videoData, setVideoData] = useState(null); const [error, setError] = useState(null); // Define the Google login success handler function const googleLoginSuccessHandler = (response) => { // Initialize the YouTube API client with the user's access token gapi.load('client', () => { gapi.client.setToken({ access_token: response.accessToken }); gapi.client.load('youtube', 'v3', () => { // Make a request to the YouTube API to get data about the channel's videos gapi.client.youtube.search.list({ channelId: CHANNEL_ID, part: 'snippet,statistics', order: 'date', maxResults: 50, }).execute((response) => { if (response.error) { setError(response.error.message); } else { // Extract the video data from the API response const videoItems = response.items.map((item) => ({ id: item.id.videoId, title: item.snippet.title, publishedAt: new Date(item.snippet.publishedAt), viewCount: parseInt(item.statistics.viewCount), likeCount: parseInt(item.statistics.likeCount), })); setVideoData(videoItems); } }); }); }); }; // Define the D3.js chart creation function const createChart = () => { if (videoData) { // Group the videos by month and calculate the total view and like counts for each month const videoGroups = d3.group(videoData, (video) => d3.timeMonth(video.publishedAt)); const monthlyData = Array.from(videoGroups, ([month, videos]) => ({ month, viewCount: d3.sum(videos, (video) => video.viewCount), likeCount: d3.sum(videos, (video) => video.likeCount), })); // Sort the monthly data by date monthlyData.sort((a, b) => d3.ascending(a.month, b.month)); // Create the D3.js scales and axes const xScale = d3.scaleTime() .domain([d3.min(monthlyData, (d) => d.month), d3.max(monthlyData, (d) => d.month)]) .range([0, CHART_WIDTH]); const yScale = d3.scaleLinear() .domain([0, d3.max(monthlyData, (d) => Math.max(d.viewCount, d.likeCount))]) .range([CHART_HEIGHT, 0]); const xAxis = d3.axisBottom(xScale); const yAxis = d3.axisLeft(yScale); // Create the D3.js line generators const lineGeneratorViewCount = d3.line() .x((d) => xScale(d.month)) .y((d) => yScale(d.viewCount)); const lineGeneratorLikeCount = d3.line() .x((d) => xScale(d.month)) .y((d) => yScale(d.likeCount)); // Create the D3.js SVG element and group const svg = d3.select('#channel-growth-chart') .append('svg') .attr('width', CHART_WIDTH) .attr('height', CHART_HEIGHT); const chartGroup = svg.append('g') .attr('transform', `translate(${margin.left}, ${margin.top})`); // Append the x-axis chartGroup.append('g') .attr('class', 'x-axis') .attr('transform', `translate(0, ${CHART_HEIGHT})`) .call(xAxis); // Append the y-axis chartGroup.append('g') .attr('class', 'y-axis') .call(yAxis); // Append the line for view count chartGroup.append('path') .datum(monthlyData) .attr('class', 'line') .attr('d', lineGeneratorViewCount) .attr('fill', 'none') .attr('stroke', 'steelblue'); // Append the line for like count chartGroup.append('path') .datum(monthlyData) .attr('class', 'line') .attr('d', lineGeneratorLikeCount) .attr('fill', 'none') .attr('stroke', 'green'); } }, [videoData]); return (