#4165 HTML/JavaScript/CSS/PHP Web App to Access and Display Neo4j AuraDB Pro and Gemini

#4165 HTML/JavaScript/CSS/PHP Web App to Access and Display Neo4j AuraDB Pro and Gemini

#4165 Tell me how to host a website on Neo4j AuraDB Professional

To get straight to the point: You cannot directly host a website on Neo4j AuraDB Professional. Neo4j AuraDB is a fully managed cloud graph database service. It is designed exclusively to store, manage, and query your highly connected backend data. It does not have the capability to serve web pages (like HTML, CSS, or JavaScript files) or run web servers to clients.

However, you can easily build a website that uses Neo4j AuraDB Professional as its database. To do this, you will need a separate web hosting service to run your application code, which will communicate with your AuraDB instance behind the scenes.

Here is how that architecture works and how you can set it up:

The Architecture

  • The Database (Backend Data): Hosted on Neo4j AuraDB Professional. This is where your nodes, relationships, and graph data live.

  • The Website (Frontend/Server): Hosted on a web platform like Vercel, AWS, Heroku, or Render. This is where your actual website files and application logic live.


How to Connect a Hosted Website to Neo4j AuraDB

1. Set Up Your Neo4j AuraDB Instance

First, you need to provision your database so your website has a place to pull data from.

  • Log in to the Neo4j Aura Console.

  • Create a new AuraDB Professional instance.

  • When the instance is created, you will be provided with a Connection URI (it usually starts with neo4j+s://) and a Password.

  • Crucial Step: Save this password immediately. For security reasons, Neo4j will not show it to you again.

2. Choose a Web Hosting Provider

Select a platform to host your actual website code. The right choice depends on the programming language and framework you are using:

  • For Full-Stack/Serverless (Next.js, React, Vue): Vercel or Netlify.

  • For Backend Apps (Node.js, Python/Django, PHP, Java): Render, Railway, Heroku, or DigitalOcean.

  • For Enterprise/Heavy Duty: AWS, Google Cloud, or Microsoft Azure.

3. Securely Add Your Credentials to Your Web Host

Never hardcode your AuraDB password directly into your website's source code. Instead, use Environment Variables in your web hosting dashboard. You will typically need to set:

  • NEO4J_URI = Your connection URI (e.g., neo4j+s://<your-db-id>.databases.neo4j.io)

  • NEO4J_USERNAME = neo4j (the default user)

  • NEO4J_PASSWORD = The password you saved in Step 1.

4. Connect Your Application Code

Install the official Neo4j driver for your website's programming language. Neo4j provides official, supported drivers for languages like JavaScript/Node.js, Python, Java, Go, and .NET.

Here is a conceptual example of what the connection looks like in a Node.js web application:

const neo4j = require('neo4j-driver');

// Use the environment variables from your web host
const driver = neo4j.driver(
  process.env.NEO4J_URI,
  neo4j.auth.basic(process.env.NEO4J_USERNAME, process.env.NEO4J_PASSWORD)
);

// Now your web app can query the database!

5. Deploy Your Website

Once your code is configured to connect to AuraDB, push your code to your chosen web hosting provider. Your website is now live, and it is using Neo4j AuraDB Professional as its data engine.


Would you like me to help you write the specific database connection code for the programming language you are using for your website?


Describe how to apply PHP as a backend for the website accessing Neo4j AuraDB Profectional

Using PHP as the backend for a website powered by Neo4j AuraDB Professional is incredibly straightforward, thanks to robust community-supported tools like the laudis/neo4j-php-client, which Neo4j officially recommends for PHP environments.

Here is a step-by-step guide to setting up your PHP backend to communicate with your Neo4j AuraDB Professional instance.

Prerequisites

  • PHP installed on your system (PHP 7.4 or higher).

  • Composer (the PHP package manager) installed.

  • Your Neo4j AuraDB Professional Credentials (Connection URI starting with neo4j+s://, username, and password).


Step 1: Install the Neo4j PHP Client

Open your terminal, navigate to your PHP project directory, and use Composer to install the Laudis Neo4j PHP Client. This library supports the neo4j+s:// protocol required by AuraDB.

composer require laudis/neo4j-php-client

Note: You may also want to install a library like vlucas/phpdotenv to manage your environment variables securely.

Step 2: Store Your Credentials Securely

Never hardcode your AuraDB password into your PHP files. Instead, create a .env file in the root of your project:

NEO4J_URI=neo4j+s://<your-database-id>.databases.neo4j.io
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=your_super_secret_password

Step 3: Initialize the Connection

In your PHP backend script (e.g., index.php or inside your framework's database configuration), you will use the ClientBuilder to establish the connection.

Here is how you connect:

<?php

require_once __DIR__ . '/vendor/autoload.php';

use Laudis\Neo4j\ClientBuilder;
use Laudis\Neo4j\Authentication\Authenticate;

// Assuming you are loading environment variables somehow (e.g., $_ENV)
$uri = $_ENV['NEO4J_URI'];
$username = $_ENV['NEO4J_USERNAME'];
$password = $_ENV['NEO4J_PASSWORD'];

// Build the Neo4j Client
$client = ClientBuilder::create()
    ->withDriver(
        'aura', // This is an alias for the connection
        $uri, 
        Authenticate::basic($username, $password)
    )
    ->withDefaultDriver('aura') // Set it as the default driver
    ->build();

echo "Successfully connected to Neo4j AuraDB!";

Step 4: Perform Database Operations

Once the client is built, you can use standard Cypher query language to read and write data to your graph.

Writing Data (e.g., Creating a User):

// Creating a node with parameters to prevent injection attacks
$result = $client->run(
    'CREATE (u:User {name: $name, email: $email}) RETURN u', 
    [
        'name' => 'Alice',
        'email' => 'alice@example.com'
    ]
);

echo "Created user: " . $result->first()->get('u')->getProperty('name');

Reading Data (e.g., Fetching Nodes):

// Match all User nodes and return their names
$results = $client->run('MATCH (u:User) RETURN u.name AS name, u.email AS email LIMIT 10');

foreach ($results as $record) {
    echo "Name: " . $record->get('name') . " | Email: " . $record->get('email') . "<br>";
}

Advanced Usage: Transaction Functions

For a cloud database like AuraDB Professional, network hiccups can occasionally happen. The safest way to interact with AuraDB is by using Transaction Functions, which automatically retry your queries if a transient error occurs.

use Laudis\Neo4j\Contracts\TransactionInterface;

$email = 'alice@example.com';

$result = $client->writeTransaction(function (TransactionInterface $tsx) use ($email) {
    return $tsx->run(
        'MATCH (u:User {email: $email}) RETURN u.name AS name', 
        ['email' => $email]
    );
});

echo "Fetched: " . $result->first()->get('name');

Would you like me to show you how to structure this database connection inside a specific PHP framework, like Laravel or Symfony?


How would the knowledge graph query results be visualized on the website without requiring Python?

To visualize your knowledge graph on the web without touching Python, the standard and most performant approach is to use frontend JavaScript libraries.

Since you are already setting up a PHP backend, the workflow is highly efficient: your PHP server runs the Cypher queries against Neo4j AuraDB, converts the raw graph data into a clean JSON format, and sends it to the user's browser. A JavaScript library then takes that JSON and draws the interactive nodes and edges directly on your web page.

This approach is entirely independent of Python. By rendering directly in the browser via JavaScript, you completely bypass the sandbox display errors and complex dependency chains that can occasionally break Python-based visualizers like pyvis in notebook environments. The browser's native rendering engine handles all the heavy lifting.

Here are the best JavaScript libraries for visualizing Neo4j data on a web frontend:

1. Cytoscape.js (The Highly Customizable Powerhouse)

  • What it is: An open-source, highly optimized graph theory library.

  • Why it's great: It allows for deep customization of every single visual element. It handles interactive events (clicking, dragging, zooming) flawlessly and features a massive ecosystem of extensions for different layout algorithms (such as force-directed, circular, or hierarchical).

  • Best for: Production-grade websites where you need the graph to look polished, highly interactive, and seamlessly integrated into your specific UI design.

2. Neovis.js (The Quickest Neo4j Integration)

  • What it is: A library specifically built by Neo4j Labs that combines the Neo4j JavaScript driver with vis.js (a popular graphing library).

  • Why it's great: It understands Cypher natively. You can map Neo4j properties directly to visual elements—for example, automatically making a node's radius larger based on its PageRank score, or coloring nodes based on their community label.

  • Best for: Rapid prototyping and internal tools where you want to get a graph on the screen with minimal configuration.

3. Sigma.js (The Performance King)

  • What it is: A WebGL-based graphing library.

  • Why it's great: If your knowledge graph query pulls thousands or tens of thousands of nodes onto the screen at once, standard SVG or Canvas-based libraries will lag or crash the browser. Sigma.js leverages the device's GPU to render massive, dense networks smoothly.

  • Best for: Extremely large datasets where rendering speed and performance are the absolute top priorities.

4. Neo4j Visualization Library (NVL)

  • What it is: Neo4j's official visualization library, which relies on the exact same underlying technology that powers the Neo4j Bloom exploration tool.

  • Why it's great: It is built for scale and deep Neo4j integration, offering smooth, high-performance rendering of complex graph structures directly supported by the Neo4j team.

  • Best for: Enterprise-level applications or when you want the exact look, feel, and performance of Neo4j's native exploration tools embedded within your own application.


The Recommended Architecture for Your Setup

To keep your AuraDB Professional credentials secure, you should never expose your database password in the frontend HTML or JavaScript. Instead, use a proxy architecture:

  1. Frontend: The user triggers an action on your website, causing JavaScript to make an asynchronous fetch request to your backend.

  2. Backend: Your PHP script securely connects to AuraDB, executes the Cypher query, and formats the result into a simple JSON array of nodes and links.

  3. Visualization: The PHP script sends the JSON back to the frontend, where a library like Cytoscape.js parses it and draws the interactive graph on the screen.

Would you like me to write a quick boilerplate showing how to take a Cypher query result from your PHP backend and draw it on the screen using Cytoscape.js?


How would the query results from AuraDB be passed to the JavaScript routine for display?

To pass the query results from your Neo4j AuraDB database to a JavaScript visualization library like Cytoscape.js, you need a "bridge" to translate the data. That bridge is JSON (JavaScript Object Notation).

The modern and most secure way to do this is to treat your PHP script as a mini-API. The PHP script fetches the raw data from Neo4j, formats it into the specific JSON structure that Cytoscape.js expects, and outputs it. Then, your frontend JavaScript fetches that JSON and draws the graph.

Here is exactly how you build that pipeline.

Step 1: Format the Data in PHP

Cytoscape.js expects graph data to be formatted into two distinct arrays: nodes and edges. Every item in these arrays must have a data object containing at least an id. Edges must also specify a source and target.

Create a PHP file (e.g., graph_api.php) to run your query and format the array:

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Laudis\Neo4j\ClientBuilder;
use Laudis\Neo4j\Authentication\Authenticate;

// 1. Connect to AuraDB
$client = ClientBuilder::create()
    ->withDriver('aura', $_ENV['NEO4J_URI'], Authenticate::basic($_ENV['NEO4J_USERNAME'], $_ENV['NEO4J_PASSWORD']))
    ->build();

// 2. Run a query that returns nodes and relationships
$results = $client->run('MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 50');

// 3. Initialize the arrays expected by Cytoscape.js
$elements = [
    'nodes' => [],
    'edges' => []
];

// Track added node IDs to prevent duplicates in the JSON output
$addedNodes = []; 

// 4. Loop through the results and map them
foreach ($results as $record) {
    $n = $record->get('n');
    $m = $record->get('m');
    $r = $record->get('r');

    $n_id = (string)$n->getProperty('id', $n->getId()); // Fallback to internal ID
    $m_id = (string)$m->getProperty('id', $m->getId());
    
    // Add source node if we haven't already
    if (!isset($addedNodes[$n_id])) {
        $elements['nodes'][] = [
            'data' => [
                'id' => $n_id,
                'label' => $n->getProperty('name', 'Unknown') // Map a property to a label
            ]
        ];
        $addedNodes[$n_id] = true;
    }

    // Add target node if we haven't already
    if (!isset($addedNodes[$m_id])) {
        $elements['nodes'][] = [
            'data' => [
                'id' => $m_id,
                'label' => $m->getProperty('name', 'Unknown')
            ]
        ];
        $addedNodes[$m_id] = true;
    }

    // Add the relationship (edge)
    $elements['edges'][] = [
        'data' => [
            'id' => (string)$r->getId(),
            'source' => $n_id,
            'target' => $m_id,
            'label' => $r->getType() // e.g., "KNOWS", "PART_OF"
        ]
    ];
}

// 5. Output the data as JSON
header('Content-Type: application/json');
echo json_encode($elements);

Step 2: Fetch and Display in JavaScript

Now, in your frontend HTML file, you will use the native JavaScript fetch() API to call the PHP file, grab the JSON, and hand it over to Cytoscape.js.

<!DOCTYPE html>
<html>
<head>
    <title>Knowledge Graph</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.28.1/cytoscape.min.js"></script>
    <style>
        /* The container must have physical dimensions */
        #cy { width: 100vw; height: 100vh; display: block; }
    </style>
</head>
<body>

    <div id="cy"></div>

    <script>
        // 1. Fetch the JSON generated by your PHP script
        fetch('graph_api.php')
            .then(response => response.json())
            .then(graphData => {
                
                // 2. Initialize Cytoscape
                var cy = cytoscape({
                    container: document.getElementById('cy'),
                    
                    // Pass the fetched data directly into the elements property
                    elements: graphData,

                    // 3. Define the visual style
                    style: [
                        {
                            selector: 'node',
                            style: {
                                'background-color': '#0074D9',
                                'label': 'data(label)', // Pulls the label from our PHP output
                                'color': '#fff',
                                'text-valign': 'center'
                            }
                        },
                        {
                            selector: 'edge',
                            style: {
                                'width': 2,
                                'line-color': '#AAAAAA',
                                'target-arrow-color': '#AAAAAA',
                                'target-arrow-shape': 'triangle',
                                'curve-style': 'bezier',
                                'label': 'data(label)',
                                'font-size': '10px'
                            }
                        }
                    ],

                    // 4. Choose an automatic layout algorithm
                    layout: {
                        name: 'cose', // A physics simulation layout
                        animate: true
                    }
                });

            })
            .catch(error => console.error("Error fetching graph data:", error));
    </script>
</body>
</html>

Why This Approach is Best

  • Separation of Concerns: Your PHP handles the secure database connection and data shaping, while your JavaScript purely handles the UI.

  • Security: Your Neo4j password never touches the user's browser.

  • Performance: You bypass loading entire web pages just to update the graph. You can trigger new fetch() calls later (e.g., when a user clicks a button) to seamlessly update the visualization without refreshing the page.

Would you like me to walk through how to add interactivity to this frontend, such as making a node expand its connected neighbors when a user clicks on it?


How would text responses be returned for display on the web page?

To display text responses on the web page alongside your knowledge graph, you will use the exact same fetch() API pipeline we just established.

Instead of having your PHP script only return the nodes and edges for Cytoscape.js, you will structure your JSON payload to include a separate section for your text. Then, your frontend JavaScript will parse that JSON, hand the graph data to Cytoscape, and inject the text data directly into the HTML of your page.

Here is how to modify the previous setup to handle both graph data and text responses simultaneously.

Step 1: Update the HTML to Hold the Text

You need a designated spot on your web page (like a <div> or a <p> tag) where the JavaScript can insert the text.

<!DOCTYPE html>
<html>
<head>
    <title>Knowledge Graph & Text</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.28.1/cytoscape.min.js"></script>
    <style>
        /* A simple layout: text on top, graph on the bottom */
        body { font-family: sans-serif; margin: 20px; }
        #text-panel { 
            padding: 15px; 
            background-color: #f4f4f4; 
            border-left: 5px solid #0074D9;
            margin-bottom: 20px;
        }
        #cy { width: 100%; height: 600px; border: 1px solid #ccc; display: block; }
    </style>
</head>
<body>

    <div id="text-panel">
        <h3 style="margin-top:0;">Database Response:</h3>
        <p id="response-text">Loading data...</p>
    </div>

    <div id="cy"></div>

    </body>
</html>

Step 2: Update the PHP to Return Both Data Types

Modify your PHP script so that the final JSON output is an object containing two distinct keys: one for the graph data and one for the text message.

<?php
// ... (Your Neo4j Connection Code Here) ...

// Let's say you queried a specific node to get a summary
$summaryText = "This knowledge graph displays 50 relationships. The central node represents the main topic.";

// ... (Your loop to build the $elements array for nodes and edges) ...

// Instead of just returning the elements, bundle them into a larger array
$finalPayload = [
    'text_response' => $summaryText, // Your text string
    'graph_data'    => $elements     // Your Cytoscape nodes/edges
];

// Output the bundled data as JSON
header('Content-Type: application/json');
echo json_encode($finalPayload);

Step 3: Update the JavaScript to Route the Data

Now, update the fetch() routine in your frontend HTML to unpack this bundled JSON payload. It will send the text to the DOM (Document Object Model) and the graph data to Cytoscape.

<script>
    fetch('graph_api.php')
        .then(response => response.json())
        .then(payload => {
            
            // 1. Inject the text into the HTML page
            // We use standard JavaScript DOM manipulation to find the <p> tag and change its text
            document.getElementById('response-text').innerText = payload.text_response;

            // 2. Pass the graph data to Cytoscape
            var cy = cytoscape({
                container: document.getElementById('cy'),
                
                // Note: We now reference payload.graph_data instead of the whole response
                elements: payload.graph_data, 

                style: [ /* ... your styles ... */ ],
                layout: { name: 'cose', animate: true }
            });

        })
        .catch(error => {
            console.error("Error fetching data:", error);
            document.getElementById('response-text').innerText = "An error occurred while loading the data.";
        });
</script>

Dynamic Text Updates via Interaction

This architecture makes it very easy to update the text based on what the user does with the graph.

For example, Cytoscape.js allows you to listen for clicks. You could write a routine where clicking a node triggers a new fetch() request to a different PHP script (e.g., get_node_details.php?id=123), which returns fresh text to display in the #text-panel without needing to redraw the entire graph or refresh the page.

Would you like me to provide the JavaScript code snippet that makes the text panel update dynamically whenever a user clicks on a specific node?


Would this setup support prompting and responses to/from Google Gemini 3?

Yes, absolutely. This setup is fully capable of supporting prompts and responses to and from the Google Gemini API.

In fact, this architecture is a highly effective foundation for building a software AI-chat sequence application. By keeping the database and AI API calls on the backend, you ensure your credentials remain completely secure while keeping the frontend lightweight and interactive.

Here is how the data flows when you introduce Gemini into this specific stack:

The Architecture Flow for Gemini Integration

1. The Frontend (JavaScript & HTML) The user types a prompt into a chat box on your webpage. When they hit "Send," your JavaScript intercepts the text and uses the fetch() API to send the prompt asynchronously to your PHP backend.

2. The Backend (PHP & Neo4j) Your PHP script acts as the orchestrator. This is where this setup lends itself perfectly to advanced context engineering (specifically, Retrieval-Augmented Generation, or RAG).

  • PHP receives the user's prompt.

  • PHP queries your Neo4j AuraDB Professional instance to find graph data relevant to the prompt.

  • PHP bundles the user's original prompt together with the retrieved graph data to create a highly contextualized prompt.

3. The Gemini API Call PHP then makes a secure HTTP request to the Gemini REST API. Because this happens on the server, your GEMINI_API_KEY is safely hidden in your .env file and never exposed to the public internet.

To handle the API communication in PHP, you have two primary options:

  • The Community Package: You can use Composer to install a community-maintained library like google-gemini-php/client, which provides a clean, object-oriented wrapper for the API.

  • Direct REST Calls: You can use a standard HTTP client like Guzzle (or native PHP cURL) to make direct POST requests to the Gemini endpoints. This gives you absolute control over the payload and streaming responses.

4. The Return Trip Once Gemini generates the response, your PHP script receives it, formats it (perhaps bundling it with the updated Neo4j nodes and edges), and passes it back to the JavaScript frontend as a JSON payload. The JavaScript then updates the chat UI with Gemini's text and redraws the Cytoscape.js graph if the context has changed.


Would you like me to write out the PHP code showing how to use Guzzle to securely send a prompt and graph context to the Gemini API?


Provide an HTML, JavaScript, CSS, PHP application to query Neo4J AuraDB Professional and Google Gemini 3 to display text and graph-based responses

Here is a complete, full-stack application that meets your requirements. It uses HTML, CSS, and JavaScript (with Cytoscape.js) for the frontend UI, and PHP for the backend to securely interact with both Neo4j AuraDB Professional and the Google Gemini REST API.

(Note: As Gemini 3.1 Pro, I have structured this to use the latest standard Gemini REST API endpoints available to developers.)

Project Structure

You will need two files in your project directory:

  1. api.php (The backend controller)

  2. index.html (The frontend UI)

You will also need to install the Neo4j PHP client via Composer in your project folder:

composer require laudis/neo4j-php-client


1. The Backend: api.php

This script receives the prompt from the frontend, queries Neo4j for context, sends both the prompt and the graph context to Gemini, and returns the bundled data.

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Laudis\Neo4j\ClientBuilder;
use Laudis\Neo4j\Authentication\Authenticate;

header('Content-Type: application/json');

// --- Configuration ---
// In a production environment, load these from a secure .env file
$neo4jUri = 'neo4j+s://YOUR_AURA_DB_ID.databases.neo4j.io';
$neo4jUser = 'neo4j';
$neo4jPass = 'YOUR_NEO4J_PASSWORD';
$geminiApiKey = 'YOUR_GEMINI_API_KEY';

// --- 1. Get User Prompt ---
$input = json_decode(file_get_contents('php://input'), true);
$userPrompt = $input['prompt'] ?? 'Summarize the data.';

// --- 2. Query Neo4j AuraDB ---
try {
    $client = ClientBuilder::create()
        ->withDriver('aura', $neo4jUri, Authenticate::basic($neo4jUser, $neo4jPass))
        ->build();

    // A generic query to pull a small subset of your graph
    $results = $client->run('MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 15');
    
    $elements = ['nodes' => [], 'edges' => []];
    $addedNodes = [];
    $graphContextForGemini = [];

    foreach ($results as $record) {
        $n = $record->get('n');
        $m = $record->get('m');
        $r = $record->get('r');

        $n_id = (string)$n->getId();
        $m_id = (string)$m->getId();
        
        // Node labels (fallback to ID if 'name' property doesn't exist)
        $n_label = $n->getProperty('name', $n->labels()[0] ?? $n_id);
        $m_label = $m->getProperty('name', $m->labels()[0] ?? $m_id);
        $r_type = $r->getType();

        // Build Cytoscape JSON
        if (!isset($addedNodes[$n_id])) {
            $elements['nodes'][] = ['data' => ['id' => $n_id, 'label' => $n_label]];
            $addedNodes[$n_id] = true;
        }
        if (!isset($addedNodes[$m_id])) {
            $elements['nodes'][] = ['data' => ['id' => $m_id, 'label' => $m_label]];
            $addedNodes[$m_id] = true;
        }
        $elements['edges'][] = [
            'data' => ['id' => (string)$r->getId(), 'source' => $n_id, 'target' => $m_id, 'label' => $r_type]
        ];

        // Build text context for Gemini
        $graphContextForGemini[] = "{$n_label} -[{$r_type}]-> {$m_label}";
    }
} catch (Exception $e) {
    echo json_encode(['error' => 'Database connection failed: ' . $e->getMessage()]);
    exit;
}

// --- 3. Query Google Gemini API ---
// Combine the user's prompt with the data extracted from Neo4j (Basic RAG)
$augmentedPrompt = "Context from database:\n" . implode("\n", $graphContextForGemini) . "\n\nUser Question: " . $userPrompt;

$geminiUrl = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=' . $geminiApiKey;

$geminiPayload = json_encode([
    'contents' => [
        ['parts' => [['text' => $augmentedPrompt]]]
    ]
]);

$ch = curl_init($geminiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $geminiPayload);

$geminiResponseRaw = curl_exec($ch);
curl_close($ch);

$geminiResponseData = json_decode($geminiResponseRaw, true);
$aiText = $geminiResponseData['candidates'][0]['content']['parts'][0]['text'] ?? "No response generated.";

// --- 4. Return Bundled Payload to Frontend ---
echo json_encode([
    'text_response' => $aiText,
    'graph_data' => $elements
]);

2. The Frontend: index.html

This file handles the layout, the user input, the fetch() request to your PHP API, and the drawing of the Cytoscape graph.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Graph & AI Chat App</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.28.1/cytoscape.min.js"></script>
    <style>
        body { font-family: system-ui, sans-serif; margin: 0; padding: 20px; display: flex; flex-direction: column; height: 100vh; box-sizing: border-box; background-color: #f9f9f9; }
        .header { margin-bottom: 20px; }
        .container { display: flex; flex: 1; gap: 20px; overflow: hidden; }
        .chat-panel { width: 35%; display: flex; flex-direction: column; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        .graph-panel { width: 65%; background: #fff; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); position: relative; }
        
        #response-box { flex: 1; overflow-y: auto; background: #f0f4f8; padding: 15px; border-radius: 6px; margin-bottom: 15px; white-space: pre-wrap; line-height: 1.5; }
        #prompt-input { width: 100%; padding: 10px; margin-bottom: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }
        button { padding: 10px 20px; background-color: #0074D9; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; }
        button:hover { background-color: #005bb5; }
        
        /* The Cytoscape container must fill its parent */
        #cy { width: 100%; height: 100%; position: absolute; top: 0; left: 0; }
    </style>
</head>
<body>

    <div class="header">
        <h2>Neo4j + Gemini Knowledge Assistant</h2>
    </div>

    <div class="container">
        <div class="chat-panel">
            <div id="response-box">Welcome! Ask a question about your graph data.</div>
            <input type="text" id="prompt-input" placeholder="e.g., What insights can you draw from this data?" onkeypress="handleKeyPress(event)">
            <button onclick="sendQuery()">Ask Gemini</button>
        </div>

        <div class="graph-panel">
            <div id="cy"></div>
        </div>
    </div>

    <script>
        let cy = cytoscape({ container: document.getElementById('cy') });

        function handleKeyPress(e) {
            if (e.key === 'Enter') sendQuery();
        }

        async function sendQuery() {
            const promptInput = document.getElementById('prompt-input');
            const responseBox = document.getElementById('response-box');
            const prompt = promptInput.value.trim();

            if (!prompt) return;

            // UI Loading state
            responseBox.innerHTML = "<em>Querying Neo4j and generating Gemini response...</em>";
            promptInput.value = '';

            try {
                // Call our PHP backend
                const response = await fetch('api.php', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ prompt: prompt })
                });

                const data = await response.json();

                if (data.error) {
                    responseBox.innerHTML = `<span style="color:red;">Error: ${data.error}</span>`;
                    return;
                }

                // 1. Update Text UI
                responseBox.innerText = data.text_response;

                // 2. Update Graph UI
                drawGraph(data.graph_data);

            } catch (err) {
                console.error(err);
                responseBox.innerHTML = `<span style="color:red;">Network or server error occurred.</span>`;
            }
        }

        function drawGraph(elements) {
            cy.destroy(); // Clear old graph
            
            cy = cytoscape({
                container: document.getElementById('cy'),
                elements: elements,
                style: [
                    {
                        selector: 'node',
                        style: {
                            'background-color': '#0074D9',
                            'label': 'data(label)',
                            'color': '#333',
                            'text-valign': 'bottom',
                            'text-margin-y': 5,
                            'font-size': '12px'
                        }
                    },
                    {
                        selector: 'edge',
                        style: {
                            'width': 2,
                            'line-color': '#ccc',
                            'target-arrow-color': '#ccc',
                            'target-arrow-shape': 'triangle',
                            'curve-style': 'bezier',
                            'label': 'data(label)',
                            'font-size': '10px',
                            'text-rotation': 'autorotate',
                            'color': '#777'
                        }
                    }
                ],
                layout: {
                    name: 'cose', // Force-directed layout
                    padding: 30,
                    animate: true
                }
            });
        }
    </script>
</body>
</html>

Would you like me to explain how to format the Gemini response (which often includes Markdown) into proper HTML for the chat window using JavaScript?


From <https://gemini.google.com/app/>  Google Gemini 3.1 (Pro)

Comments

Popular posts from this blog

#2892 Example of ChatGPT o1 Prompt

#3105 Federal and State Spending Idiocy