ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Custom Indicator in FinanceChart
Posted by Takeshi on Mar-20-2021 15:22
Attachments:
Hi Peter,

I manage to produce a heat map indicator subroutine into FinanceChart.h. However I have difficulty of removing duplicated x-axis labels in the FinanceChart. Also, how could I move border and vertical grid lines to the front of heat map? I have been trying for some times but still cannot solve the problems.

Below is my code:

public: XYChart* addMarketBreadthHM(int height, int color_low, int color_high)
{
        int sectorno = m_marketbreadthsector.size();
        std::vector<std::string> m_marketbreadthsector_str(sectorno);
        for(int i=0;i<sectorno;i++)
        {
            std::string strbuff = m_marketbreadthsector[i].toUtf8().constData();
            m_marketbreadthsector_str[i] = strbuff.substr(0, 2);
        }

        // We need to layout the chart first to determine the x-axis scale
        layout();

        // Add an empty indicator chart
        XYChart *c = addIndicator(height);

        // Add the labels to the y-axis
        c->yAxis()->setLinearScale(0, sectorno - 1,
               StrVecToStringArray(m_marketbreadthsector_str));
        c->yAxis()->setIndent(true);
        c->yAxis()->setTickColor(Chart::Transparent,Chart::Transparent);
        c->yAxis()->setTopMargin(0);

        // We can use a hidden color axis to translate the cell values to colors
        ColorAxis* cAxis = c->addContourLayer(DoubleArray(), DoubleArray(),
               DoubleArray())->colorAxis();
        cAxis->setLinearScale(0, 100);
        int colors[] = {color_low,0xffffff,color_high};
        cAxis->setColorGradient(true, IntArray(colors, (int)
               (sizeof(colors)/sizeof(*colors))));

        // Use the DrawArea to draw the cells as rectangles
        DrawArea* d = c->makeChart();

        for (int i = m_extraPoints; i < m_closeData.len; ++i) {
            for (int j = 0; j < sectorno; ++j) {
                int color = cAxis->getColor(m_marketbreadth[j][i]);
                d->rect(c->getXCoor(i - m_extraPoints - 0.5), c->getYCoor(j + 0.5),
                        c->getXCoor(i - m_extraPoints + 0.5), c->getYCoor(j - 0.5), color,
                        color);
            }
        }

        return c;
}

Thank you so much in advance

Best Regards,
Takeshi
Capture.JPG

  Re: Custom Indicator in FinanceChart
Posted by Peter Kwan on Mar-21-2021 00:18
Hi Takeshi.

May be you can try:


public: XYChart* addMarketBreadthHM(int height, int color_low, int color_high)
{
        int sectorno = m_marketbreadthsector.size();
        std::vector<std::string> m_marketbreadthsector_str(sectorno);
        for(int i=0;i<sectorno;i++)
        {
            std::string strbuff = m_marketbreadthsector[i].toUtf8().constData();
            m_marketbreadthsector_str[i] = strbuff.substr(0, 2);
        }

        // Add an empty indicator chart
        XYChart *c = addIndicator(height);

        // Add the labels to the y-axis
        c->yAxis()->setLinearScale(0, sectorno - 1,
               StrVecToStringArray(m_marketbreadthsector_str));
        c->yAxis()->setIndent(true);
        c->yAxis()->setTickColor(Chart::Transparent,Chart::Transparent);
        c->yAxis()->setTopMargin(0);

        // We can use a hidden color axis to translate the cell values to colors
        ColorAxis* cAxis = c->addContourLayer(DoubleArray(), DoubleArray(),
               DoubleArray())->colorAxis();
        cAxis->setLinearScale(0, 100);
        int colors[] = {color_low,0xffffff,color_high};
        cAxis->setColorGradient(true, IntArray(colors, (int)
               (sizeof(colors)/sizeof(*colors))));

        // We need to layout the chart first to determine the x-axis scale
        layout();

        // Get the DrawArea for drawing at the chart background so that the drawing
        // will be behind grid lines
        DrawArea* d = c->getDrawArea();

        // Make sure the plot area is transparent to prevent it from hiding background drawing
        c->getPlotArea()->setBackground(Chart::Transparent);

        for (int i = m_extraPoints; i < m_closeData.len; ++i) {
            for (int j = 0; j < sectorno; ++j) {
                int color = cAxis->getColor(m_marketbreadth[j][i]);
                d->rect(c->getXCoor(i - m_extraPoints - 0.5), c->getYCoor(j + 0.5),
                        c->getXCoor(i - m_extraPoints + 0.5), c->getYCoor(j - 0.5), color,
                        color);
            }
        }

        return c;
}


The main changes are:

(a) The layout(); is moved to just before the getDrawArea, so that it will layout all the charts so far including the indicator chart "c".

(b) Instead of using makeChart() to get the DrawArea, we use getDrawArea(). This gets the drawarea without drawing the chart first, which means the rectangles will draw on the background and will not cover the grid lines. We need to make sure the plot area is transparent so we can see the drawings.

If we use makeChart, it will draw the chart first. The rectangles will then stay in front of the grid lines and hide them. Also, when we call makeChart, the chart it is the bottom chart (the other indicators are added later), so it will include the x-axis labels. Not calling makeChart can solve these two problems.

Regards
Peter Kwan

  Re: Custom Indicator in FinanceChart
Posted by Takeshi on Mar-21-2021 13:12
Attachments:
Hi Peter,

Thank you so much for your prompt reply. I found that with this solution I can only produce the heatmap indicator once to the FinanceChart. It appears empty if I add an identical heat maps underneath, but this minor problem can be solved by restricting showing identical indicator. It would be much appreciated if you have better solution.

Thank you.

Best Regards,
Takeshi
Capture.JPG

  Re: Custom Indicator in FinanceChart
Posted by Peter Kwan on Mar-21-2021 15:37
Hi Takeshi,

For each chart object, you can only call "layout();" once. The second time it is called, it has no effect.

In the heat map code, the layout is called to layout the FinanceChart. For the second heat map, it is called the second time, and it has no effect. That's why the second heat map does not work.

Because the charts are interdependent (each chart relies on the x-axis of the previous chart), so what we need is to layout all the XYChart objects. Calling layout for the FinanceChart automatically layout all XYChart objects, but it cannot be called again, so it does not apply to the XYChart objects added after layout.

For your case,  instead of "layout();", may be you can use:

// Layout all the XYCharts
for (int j = 0; c->getChart(j); ++j)
   c->getChart(j)->layout();

Hope this can help.

Regards
Peter Kwan