Map<String, Long> coord = new LinkedHashMap<>();
for (int i = 0; i < width; i++)
{
s.append("<tr>\n");
Column column = topColumns.get(i);
String colId = makeColumnId(topAxisName, i);
s.append(" <th data-id=\"").append(colId);
s.append("\" class=\"th-ncube ");
s.append(getColumnCssClass(topAxis, column));
s.append("\">");
addColumnPrefixText(s, column);
s.append(column.isDefault() ? "Default" : column.toString());
coord.clear();
coord.put(topAxisName, (long) i);
s.append("</th>\n");
Set<Long> colIds = new HashSet<>();
colIds.add(column.getId());
buildCell(ncube, s, coord, colIds);
s.append("</tr>\n");
}
}
else
{ // 2D+ shows as one column on the X axis and all other dimensions on the Y axis.
int deadCols = axes.size() - 1;
if (deadCols > 0)
{
s.append(" <th class=\"th-ncube ncube-dead\" colspan=\"").append(deadCols).append("\">");
s.append(ncube.getName());
s.append("</th>\n");
}
s.append(" <th data-id=\"a").append(topAxis.getId()).append("\" class=\"th-ncube ncube-head\" colspan=\"");
s.append(topAxis.size());
s.append("\">");
s.append(" <div class=\"btn-group axis-menu\" data-id=\"").append(topAxisName).append("\">\n");
s.append(" <button type=\"button\" class=\"btn-sm btn-primary dropdown-toggle axis-btn\" data-toggle=\"dropdown\">");
s.append(" <span>").append(topAxisName).append("</span><span class=\"caret\"></span>");
s.append(" </button>\n");
s.append(" </div>\n");
s.append(" </th>\n</tr>\n");
// Second row (special case)
s.append("<tr>\n");
Map<String, Long> rowspanCounter = new HashMap<>();
Map<String, Long> rowspan = new HashMap<>();
Map<String, Long> columnCounter = new HashMap<>();
Map<String, List<Column>> columns = new HashMap<>();
final int axisCount = axes.size();
for (int i = 1; i < axisCount; i++)
{
Axis axis = axes.get(i);
String axisName = axis.getName();
s.append(" <th data-id=\"a").append(axis.getId()).append("\" class=\"th-ncube ncube-head\">\n");
s.append(" <div class=\"btn-group axis-menu\" data-id=\"").append(axisName).append("\">\n");
s.append(" <button type=\"button\" class=\"btn-sm btn-primary dropdown-toggle axis-btn\" data-toggle=\"dropdown\">");
s.append(" <span>").append(axisName).append("</span><span class=\"caret\"></span>");
s.append(" </button>\n");
s.append(" </div>\n");
s.append(" </th>\n");
long colspan = 1;
for (int j = i + 1; j < axisCount; j++)
{
colspan *= axes.get(j).size();
}
rowspan.put(axisName, colspan);
rowspanCounter.put(axisName, 0L);
columnCounter.put(axisName, 0L);
columns.put(axisName, axis.getColumns());
}
for (Column column : topColumns)
{
String colId = makeColumnId(topAxisName, column.getDisplayOrder());
s.append(" <th data-id=\"").append(colId).append("\" class=\"th-ncube-top ");
s.append(getColumnCssClass(topAxis, column));
s.append("\">");
addColumnPrefixText(s, column);
s.append(column.toString());
s.append("</th>\n");
}
if (topAxis.size() != topColumnSize)
{
s.append(" <th class=\"th-ncube-top ");
s.append(getColumnCssClass(topAxis, topAxis.getDefaultColumn()));
s.append("\">Default</th>");
}
s.append("</tr>\n");
Map<String, Long> coord = new HashMap<>();
Map<String, Long> colIds = new HashMap<>();
// The left column headers and cells
for (long h = 0; h < height; h++)
{
s.append("<tr>\n");
// Column headers for the row
for (int i = 1; i < axisCount; i++)
{
Axis axis = axes.get(i);
String axisName = axis.getName();
Long count = rowspanCounter.get(axisName);
if (count == 0)
{
Long colIdx = columnCounter.get(axisName);
Column column = columns.get(axisName).get(colIdx.intValue());
coord.put(axisName, colIdx);
colIds.put(axisName, column.getId());
long span = rowspan.get(axisName);
String columnId = makeColumnId(axisName, colIdx);
String colCssClass = getColumnCssClass(axis, column);
if (span == 1)
{ // drop rowspan tag since rowspan="1" is redundant and wastes space in HTML
// Use column's ID as TH element's ID
s.append(" <th data-id=\"").append(columnId).append("\" class=\"th-ncube ");
s.append(colCssClass);
s.append("\">");
}
else
{ // Need to show rowspan attribute
// Use column's ID as TH element's ID
s.append(" <th data-id=\"").append(columnId).append("\" class=\"th-ncube ");
s.append(colCssClass);
s.append("\" rowspan=\"");
s.append(span);
s.append("\">");
}
addColumnPrefixText(s, column);
s.append(column.toString());
s.append("</th>\n");
// Increment column counter
colIdx++;
if (colIdx >= axis.size())
{
colIdx = 0L;
}
columnCounter.put(axisName, colIdx);
}
// Increment row counter (counts from 0 to rowspan of subordinate axes)
count++;
if (count >= rowspan.get(axisName))
{
count = 0L;
}
rowspanCounter.put(axisName, count);
}
// Cells for the row
for (int i = 0; i < width; i++)
{
Column column = topColumns.get(i);
colIds.put(topAxisName, column.getId());
coord.put(topAxisName, (long)i);
// Other coordinate values are set above this for-loop
buildCell(ncube, s, coord, new HashSet<>(colIds.values()));
}