Challenges with utilizing amcharts

I'm using the amcharts library to create stock charts. Here's my progress so far: https://i.sstatic.net/NVX8P.png

And here's my desired outcome: https://i.sstatic.net/8eIZh.png

Upon comparing both images, you'll notice that I have successfully implemented cylindrical and moving average graphs (dashed lines), but I'm struggling to add spikes at the bottom of the graph like in the original image (pink and orange colors). I'm unsure how to incorporate these spikes into the stock graph as my data is dynamic, making it challenging to create a js fiddle. However, I am able to provide my function here-

function load_stock_graph(graph_type, history, title, aggregate){
    // DEFINE CHART PLUGINS
    AmCharts.averageGraphs = 0;
    AmCharts.addMovingAverage = function (dataSet, panel, field, aggregate, col ,graph) {
        // update dataset
        var avgField = "avg"+AmCharts.averageGraphs;
        dataSet.fieldMappings.push({
            fromField: avgField,
            toField: avgField});

        // calculate moving average
        var fc = 0;
        var sum = 0;
        for (var i = 0; i < dataSet.dataProvider.length; i++) {
           // console.log(aggregate[i].ema_0008)
            var dp = dataSet.dataProvider[i];
            if (dp[field] !== undefined) {
                sum += dp[field];
                fc++;
                if (aggregate[i] !== undefined){
                    if(col == '08'){
                        dp[avgField] = aggregate[i].ema_0008;
                    }else if(col == '15'){
                        dp[avgField] = aggregate[i].ema_0015;
                    }else if(col == '20'){
                        dp[avgField] = aggregate[i].ema_0020;
                    }
                }
            }
        }

        // create a graph
        graph.valueField = avgField;
        panel.stockGraphs.push(graph);

        // increment average graph count
        AmCharts.averageGraphs++;
    }

    // CHART DATA
    var chartData = [];
        var chartData1 = [];

    generateChartData(history);

    function generateChartData(history) {
        var firstDate = new Date();
        firstDate.setHours(0, 0, 0, 0);
        firstDate.setDate(firstDate.getDate() - 2000);

        for (var i = 0; i < history.length; i++) {
            var date = new Date(history[i].date);

             var val = Math.round(Math.random() * (30) + 100);

            chartData[i] = ({
                date: date,
                open: history[i].open,
                close: history[i].close,
                high: history[i].high,
                low: history[i].low,
                volume: history[i].volume,
                value: val
            });



        }
    }



    // CHART CONFIG
    var chartConfig =  {
        type: "stock",
        pathToImages : "/static/img/amcharts/",

        dataSets: [{
            fieldMappings: [{
                fromField: "open",
                toField: "open"
            }, {
                fromField: "close",
                toField: "close"
            }, {
                fromField: "high",
                toField: "high"
            }, {
                fromField: "low",
                toField: "low"
            }, {
                fromField: "volume",
                toField: "volume"
            }, {
                fromField: "value",
                toField: "val"
            }],

            color: "#fff",
            dataProvider: chartData,
            title: title,
            categoryField: "date",
            compared: false,
        }, 
        {
            fieldMappings: [{
                fromField: "value",
                toField: "value"
            }],
            color: "#fff",
            dataProvider: chartData,
            title: title,
            categoryField: "date"
        },


        ],


        panels: [{
                title: "Value",
                percentHeight: 70,


                stockGraphs: [{type: graph_type,
                      id: "g1",
                      openField: "open",
                      closeField: "close",
                      highField: "high",
                      lowField: "low",
                      valueField: "close",
                      lineColor: "#fff",
                      fillColors: "#fff",
                      negativeLineColor: "#db4c3c",
                      negativeFillColors: "#db4c3c",
                      fillAlphas: 1,
                      comparedGraphLineThickness: 2,
                      columnWidth: 0.7,
                      useDataSetColors: false,
                      comparable: true,
                      compareField: "close",
                      showBalloon: false,
                      //proCandlesticks: true
                    } ],

                stockLegend: {
                    valueTextRegular: undefined,
                    periodValueTextComparing: "[[percents.value.close]]%"
                }
            },

            {
                title: "Volume",
                percentHeight: 40,
                marginTop: 1,
                columnWidth: 0.6,
                showCategoryAxis: false,
                valueAxes: [{
                    usePrefixes: true
                }],



                stockGraphs: [ {
                      valueField: "volume",
                      openField: "open",
                      type: "column",
                      showBalloon: false,
                      fillAlphas: 1,
                      lineColor: "#fff",
                      fillColors: "#fff",
                      negativeLineColor: "#db4c3c",
                      negativeFillColors: "#db4c3c",
                      useDataSetColors: false,
                    } ],

                stockLegend: {
                    markerType: "none",
                    markerSize: 0,
                    labelText: "",
                    periodValueTextRegular: "[[value.close]]"
                }
            }


        ],

        panelsSettings: {
          color: "#fff",
          plotAreaFillColors: "#333",
          plotAreaFillAlphas: 1,
          marginLeft: 60,
          marginTop: 5,
          marginBottom: 5
        },

        chartScrollbarSettings: {
            graph: "g1",
            graphType: "line",
            usePeriod: "WW",
            backgroundColor: "#333",
            graphFillColor: "#666",
            graphFillAlpha: 0.5,
            gridColor: "#555",
            gridAlpha: 1,
            selectedBackgroundColor: "#444",
            selectedGraphFillAlpha: 1
        },
        categoryAxesSettings: {
          equalSpacing: true,
          gridColor: "#555",
          gridAlpha: 1
        },

        valueAxesSettings: {
          gridColor: "#555",
          gridAlpha: 1,
          inside: false,
          showLastLabel: true
        },

        chartCursorSettings: {
            pan: true,
            valueLineEnabled:true,
            valueLineBalloonEnabled:true
        },

        legendSettings: {
          color: "#fff"
        },

        stockEventsSettings: {
          showAt: "high"
        },

        balloon: {
          textAlign: "left",
          offsetY: 10
        }, 

        periodSelector: {
            position: "bottom",

          periods: [ {
            period: "DD",
            count: 10,
            label: "10D"
          }, {
            period: "MM",
            count: 1,
            label: "1M"
          }, {
            period: "MM",
            count: 6,
            selected: true,
            label: "6M"
          }, {
            period: "YYYY",
            count: 1,
            label: "1Y"
          }, {
            period: "YYYY",
            count: 2,
            label: "2Y"
          }, {
            period: "YTD",
            label: "YTD"
          }, {
            period: "MAX",
            label: "MAX"
          } ]
        },
            "export": {
          "enabled": true,
          "backgroundColor": "#fff",
          "dataDateFormat": "YYYY-MM-DD"
        }
    }

    // ADD INDICATORS
    // ema_0008
    AmCharts.addMovingAverage(chartConfig.dataSets[0], chartConfig.panels[0], 'value',aggregate, '08', {
        useDataSetColors: false,
        color: "#ccffcc",
        lineColor: "#F4F009",
        title: "aggregate ema 0008",
        dashLength: 3
    });
    // ema_0015
    AmCharts.addMovingAverage(chartConfig.dataSets[0], chartConfig.panels[0], 'value',aggregate, '15',{
        useDataSetColors: false,
        color: "#ccffcc",
        lineColor: "#2C7F1D",
        title: "aggregate ema 0015",
        dashLength: 3
    });

    // ema_0020
    AmCharts.addMovingAverage(chartConfig.dataSets[0], chartConfig.panels[0], 'value',aggregate, '20',{
        useDataSetColors: false,
        color: "#ccffcc",
        lineColor: "#A109E8",
        title: "aggregate ema 0020",
        dashLength: 3
    });

    // Empty chart instance so that chart loaded via ajax can work correctly
    AmCharts.charts = [];

    // CREATE CHART
    var chart = AmCharts.makeChart("chartdiv", chartConfig);

}

Answer №1

It appears that adding another line graph in a separate panel would be beneficial for your needs.

Here are the steps to achieve this:

1) Incorporate an additional field in your data. In addition to open, high, low, and close fields, introduce a new field such as "pink".

2) Adjust the Data Set's fieldMappings property to reflect this change:

   [{
      fromField: "open",
      toField: "open"
    }, {
      fromField: "close",
      toField: "close"
    }, {
      fromField: "high",
      toField: "high"
    }, {
      fromField: "low",
      toField: "low"
    }, {
      fromField: "volume",
      toField: "volume"
    }, {
      fromField: "value",
      toField: "val"
    }, {
      fromField: "pink",
      toField: "pink"
    }]

3) Create an additional stock panel with a graph that utilizes the newly added data field:

  {
    percentHeight: 20,
    showCategoryAxis: false,
    stockGraphs: [{
      valueField: "pink",
      showBalloon: false,
      lineColor: "#fb02fe",
      lineThickness: 2,
      useDataSetColors: false
    }]
  }

If you wish to add the indicator to an existing panel, define the graph within its stockGraphs array. For example:

  {
    percentHeight: 20,
    showCategoryAxis: false,
    stockGraphs: [{
      valueField: "pink",
      showBalloon: false,
      lineColor: "#fb02fe",
      lineThickness: 2,
      useDataSetColors: false
    }, {
      valueField: "red",
      showBalloon: false,
      lineColor: "#cc0000",
      lineThickness: 2,
      useDataSetColors: false
    }]
  }

Repeat this process to include as many indicators as needed.

Check out a functional demo (with random values)

http://codepen.io/amcharts/pen/938b09efeabca4596c0a2cdaea60a269

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Embed images within the JavaScript bundle

Here is my scenario: I have developed a components library for React. Within this library, there is a package bundled with Rollup that contains various assets, including a GIF picture used in one of the components. The specific component utilizing this p ...

Exploring nested object values in React Js through iteration

I have been searching extensively for a solution to no avail. I have an object created from fetched data with the following structure: { id: string, title: string, price: { currency: string, amount: number, }, ...

Interactive Slideshow Generated by Foreach Iteration

Currently I am immersed in a digital signage project at my workplace, and although most of the back end work is complete, I have hit a major roadblock. The challenge lies in figuring out how to organize and display the query output in a slideshow format. R ...

Exploring the Depths of Multidimensional JSON Arrays in PHP

I am currently working on developing a web-based file manager that allows me to organize, view, create, edit, and delete folders and files. In order to store information about these folders, files, and subfolders, I am in need of an appropriate data struct ...

Reacting with Node.js: Capturing a selected option from a dropdown menu and storing it in the database

On my React frontend, I have a select dropdown like this: <select name="level" value={level} onChange={this.handleChange} className="form-control"> <option>Begineer</option> <option>Intermediate</option> <option> ...

The behavior of React's useState hook is causing values to be added to instead of replaced

Seeking real-time price updates every 5 seconds, I implemented a recursive setTimeout function. However, the current behavior of the price feed is as follows: Initially, the console displays: undefined and the current price Upon a price change, the consol ...

What is the best way to generate a basic json array on the fly?

Although this question has been asked multiple times, I am struggling to apply the solutions to my code. I need some help as I just can't seem to get it to work correctly. Here is a snippet of my code with altered variables: Code Sample: for (var k ...

Showing a coordinated timer countdown alongside automatic server-side logout

I found inspiration in this particular PHP session timer example that incorporates an AJAX call to monitor the session's 'time'. I aim to integrate a simple JavaScript countdown timer for the user, like so: function startTimer(duration, di ...

Retrieve data from a local JSON file and showcase it in a list within a Next.js project. The error "Property 'data' does not exist on type String

Having trouble displaying the names of crates (which are filled with records/albums) from a local JSON file. The names aren't showing up and I'm wondering if I should be using params or if perhaps not stringifying the JSON would help. Visual Stud ...

Ellipsis paired with divs for children

Below is the HTML code which is also linked to a Bootstrap popover: <div class="event" style="top: 0%; width: 100%;"> <span class="test">Layouts</span> <div class="value"> test </div> <span class="test">Sta ...

extract the initial letter from each word within the list item

Can I retrieve the initials of each li and then either display or replace the li value instead? I came across a JavaScript code online that extracts the initials of every word, but I want it to replace them with the value of my li elements. HTML: <ul& ...

Encountering an issue when attempting to submit a form using ajax technology

While submitting a post method form, I encountered an issue where the input fields values were not being received upon submission. When using an Ajax call in jQuery to serialize and submit the form values, everything works correctly. However, when attempti ...

Integrating Express into a React Webpack project

I am currently in the process of integrating express into my React project to establish connections with databases for storing form data. As of now, I am using webpack to create a dev server that displays my React view. My technology stack includes... Web ...

When trying to use `slug.current` in the link href(`/product/${slug.current}`), it seems to be undefined. However, when I try to log it to the console, it is displaying correctly

import React from 'react'; import Link from 'next/link'; import { urlFor } from '../lib/clients'; const Product = ({ product: { image, name, slug, price } }) => { return ( <div> <Link href={`/product/ ...

Chrome seems to be having trouble connecting via socket.io, while Firefox and Safari are able to do so without any issues. Some strange

I've been setting up a socket.io implementation for nodejs. Everything runs smoothly on most devices across various browsers, but I'm encountering an issue with Chrome on certain devices. It fails to connect to the socket server, showing this er ...

Sequentially uploading files with HTML5 Drag and Drop functionality is a breeze

I recently implemented HTML5 drag-and-drop uploads in my web app. Although I found a script that successfully enabled this feature, I now require the functionality to upload files individually rather than all at once in separate requests. Is there a way t ...

What steps can I take to enhance the efficiency of this JavaScript DOM data manipulation algorithm?

Purpose I am working with a DOM that contains around 70 elements (divs with content). I have the need to move and toggle the display of these divs frequently and rapidly. Speed is crucial in this process. The trigger for moving and toggling these divs is ...

Unexpected issue: THREE js Object position does not update after rotation

For the past couple of weeks, I've been engrossed in creating a solar system model using Three.js. After following tutorials and documentation, I successfully created a working model of the solar system. However, I encountered an issue when trying to ...

Executing PHP code from a list item

On one of my website pages, I have a list that functions as a delete button. However, I am interested in making it so that when a user clicks on the delete option, a php script is triggered - similar to how a submit button works. Below is the list structu ...

Using inline CSS in JavaScript does not seem to function properly

I'm having an issue with this code. I created a javascript variable in the same file and referenced it for setting the background color of the body. However, it's not working as expected. Can someone please explain why and help me achieve my desi ...