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

Message ListMessage List     Post MessagePost Message

  heatmap bars
Posted by Mikael on Mar-17-2017 22:30
Attachments:
Can you suggest an approach to get something like the attached image? Many thanks.
heatmapbar.png

  Re: heatmap bars
Posted by Peter Kwan on Mar-18-2017 03:33
Attachments:
Hi Mikael,

One method I can think of is to create a "dummy chart" just for the purpose of obtaining the color map. Then we can group the bars into groups based on their colors, and plot them as separate data sets.

The attached chart is generated by the color below:

//Same random values as data
const int count = 100;
double data[count];
for (int i = 0; i < count; ++i)
data[i] = (i % 45) / 10.0 - 0.5;

// Create a dummy chart with the same plot area height as the real chart
// to obtain the color map
XYChart *c0 = new XYChart(1, 1);
c0->setPlotArea(0, 0, 1, 250);
c0->addBarLayer(DoubleArray(data, count));
c0->yAxis()->setTickDensity(40);
ColorAxis *caxis0 = c0->addContourLayer(DoubleArray(), DoubleArray(),
DoubleArray())->colorAxis();
caxis0->setColorGradient(true);
caxis0->syncAxis(c0->yAxis());
c0->layout();

// The real chart
XYChart *c = new XYChart(640, 300);
c->setPlotArea(50, 20, 520, 250);
c->yAxis()->setTickDensity(40);

// Separate the data based on their colors as obtained from the color map
typedef std::map< int, std::vector<double> > BarGroups;
BarGroups barGroups;
for (int i = 0; i < count; ++i)
{
int color = caxis0->getColor(data[i]);
if (barGroups.find(color) == barGroups.end())
barGroups[color] = std::vector<double>(count, Chart::NoValue);
barGroups[color][i] = data[i];
}

// Draw the bars
BarLayer *layer = c->addBarLayer(Chart::Stack);
layer->setBorderColor(Chart::Transparent);
for (BarGroups::iterator e = barGroups.begin(); e != barGroups.end(); ++e)
layer->addDataSet(DoubleArray(&(e->second[0]), e->second.size()), e->first);

// Put the color legend on the right side of the plot area with proper labels
ContourLayer *layer1 = c->addContourLayer(DoubleArray(), DoubleArray(), DoubleArray());
ColorAxis *caxis = layer1->setColorAxis(c->getPlotArea()->getRightX(), c->getPlotArea()->getTopY(),
Chart::TopLeft, c->getPlotArea()->getHeight(), Chart::Right);
const char *labels[] = { "High", "Medium", "Low" };
caxis->setColorGradient(true);
caxis->setLinearScale(caxis0->getMinValue(), caxis0->getMaxValue(), StringArray(labels, 3));

c->makeChart("c:\\testdir\\test.png");

Hope this can help.

Regards
Peter Kwan
test.png

  Re: heatmap bars
Posted by Mikael on Mar-21-2017 03:23
Attachments:
Helpful, thanks. It gets slow for large numbers of distinct colors but we can live with that. It becomes a problem that bars overlap slightly in TouchBar mode when edgecolor is turned off.
colorbars.png