diff --git a/src/js/charts/AggregationChart.js b/src/js/charts/AggregationChart.js index 1af47d3..b9e44b3 100644 --- a/src/js/charts/AggregationChart.js +++ b/src/js/charts/AggregationChart.js @@ -15,6 +15,7 @@ export default class AggregationChart extends BaseChart { this.config.formatTooltipY = (args.tooltipOptions || {}).formatTooltipY; this.config.maxSlices = args.maxSlices || 20; this.config.maxLegendPoints = args.maxLegendPoints || 20; + this.config.legendRowHeight = 60; } calc() { @@ -70,40 +71,24 @@ export default class AggregationChart extends BaseChart { let s = this.state; this.legendArea.textContent = ""; this.legendTotals = s.sliceTotals.slice(0, this.config.maxLegendPoints); + super.renderLegend(this.legendTotals); + } - let count = 0; - let y = 0; - this.legendTotals.map((d, i) => { - let barWidth = 150; - let divisor = Math.floor( - (this.width - getExtraWidth(this.measures)) / barWidth - ); - if (this.legendTotals.length < divisor) { - barWidth = this.width / this.legendTotals.length; - } - if (count > divisor) { - count = 0; - y += 60; - } - let x = barWidth * count + 5; - let label = this.config.truncateLegends - ? truncateString(s.labels[i], barWidth / 10) - : s.labels[i]; - let formatted = this.config.formatTooltipY - ? this.config.formatTooltipY(d) - : d; - let dot = legendDot( - x, - y, - 12, - 3, - this.colors[i], - `${label}: ${formatted}`, - d, - false - ); - this.legendArea.appendChild(dot); - count++; - }); + makeLegend(data, index, x_pos, y_pos) { + let formatted = this.config.formatTooltipY + ? this.config.formatTooltipY(data) + : data; + + return legendDot( + x_pos, + y_pos, + 12, // size + 3, // dot radius + this.colors[index], // fill + this.state.labels[index], // label + formatted, // value + null, // base_font_size + this.config.truncateLegends // truncate_legends + ); } } diff --git a/src/js/charts/AxisChart.js b/src/js/charts/AxisChart.js index 3e3da20..a348db9 100644 --- a/src/js/charts/AxisChart.js +++ b/src/js/charts/AxisChart.js @@ -4,7 +4,6 @@ import { zeroDataPrep, getShortenedLabels, } from "../utils/axis-chart-utils"; -import { AXIS_LEGEND_BAR_SIZE } from "../utils/constants"; import { getComponent } from "../objects/ChartComponents"; import { getOffset, fire } from "../utils/dom"; import { @@ -16,7 +15,7 @@ import { getClosestInArray, } from "../utils/intervals"; import { floatTwo } from "../utils/helpers"; -import { makeOverlay, updateOverlay, legendBar } from "../utils/draw"; +import { makeOverlay, updateOverlay, legendDot } from "../utils/draw"; import { getTopOffset, getLeftOffset, @@ -61,6 +60,7 @@ export default class AxisChart extends BaseChart { this.config.formatTooltipY = options.tooltipOptions.formatTooltipY; this.config.valuesOverPoints = options.valuesOverPoints; + this.config.legendRowHeight = 30; } prepareData(data = this.data) { @@ -454,25 +454,24 @@ export default class AxisChart extends BaseChart { renderLegend() { let s = this.data; if (s.datasets.length > 1) { - this.legendArea.textContent = ""; - s.datasets.map((d, i) => { - let barWidth = AXIS_LEGEND_BAR_SIZE; - // let rightEndPoint = this.baseWidth - this.measures.margins.left - this.measures.margins.right; - // let multiplier = s.datasets.length - i; - let rect = legendBar( - // rightEndPoint - multiplier * barWidth, // To right align - barWidth * i, - "0", - barWidth, - this.colors[i], - d.name, - this.config.truncateLegends - ); - this.legendArea.appendChild(rect); - }); + super.renderLegend(s.datasets); } } + makeLegend(data, index, x_pos, y_pos) { + return legendDot( + x_pos, + y_pos + 5, // Extra offset + 12, // size + 3, // dot radius + this.colors[index], // fill + data.name, //label + null, // value + 8.75, // base_font_size + this.config.truncateLegends // truncate legends + ); + } + // Overlay makeOverlay() { if (this.init) { diff --git a/src/js/charts/BaseChart.js b/src/js/charts/BaseChart.js index da89a96..adb37ef 100644 --- a/src/js/charts/BaseChart.js +++ b/src/js/charts/BaseChart.js @@ -11,6 +11,7 @@ import { makeSVGGroup, makeText, } from "../utils/draw"; +import { LEGEND_ITEM_WIDTH } from "../utils/constants"; import { BASE_MEASURES, getExtraHeight, @@ -303,7 +304,25 @@ export default class BaseChart { } } - renderLegend() {} + renderLegend(dataset) { + this.legendArea.textContent = ""; + let count = 0; + let y = 0; + + dataset.map((data, index) => { + let divisor = Math.floor(this.width / LEGEND_ITEM_WIDTH); + if (count > divisor) { + count = 0; + y += this.config.legendRowHeight; + } + let x = LEGEND_ITEM_WIDTH * count; + let dot = this.makeLegend(data, index, x, y); + this.legendArea.appendChild(dot); + count++; + }); + } + + makeLegend() {} setupNavigation(init = false) { if (!this.config.isNavigable) return; diff --git a/src/js/utils/constants.js b/src/js/utils/constants.js index c4b066c..130ab04 100644 --- a/src/js/utils/constants.js +++ b/src/js/utils/constants.js @@ -76,7 +76,7 @@ export const CHART_POST_ANIMATE_TIMEOUT = 400; export const DEFAULT_AXIS_CHART_TYPE = "line"; export const AXIS_DATASET_CHART_TYPES = ["line", "bar"]; -export const AXIS_LEGEND_BAR_SIZE = 100; +export const LEGEND_ITEM_WIDTH = 150; export const SERIES_LABEL_SPACE_RATIO = 0.6; export const BAR_CHART_SPACE_RATIO = 0.5; diff --git a/src/js/utils/draw.js b/src/js/utils/draw.js index 8278eff..5ef588d 100644 --- a/src/js/utils/draw.js +++ b/src/js/utils/draw.js @@ -9,7 +9,7 @@ import { DOT_OVERLAY_SIZE_INCR } from "./constants"; export const AXIS_TICK_LENGTH = 6; const LABEL_MARGIN = 4; -const LABEL_MAX_CHARS = 15; +const LABEL_MAX_CHARS = 18; export const FONT_SIZE = 10; const BASE_LINE_COLOR = "#E2E6E9"; const FONT_FILL = "#313B44"; @@ -307,37 +307,6 @@ export function heatSquare( return createSVG("rect", args); } -export function legendBar(x, y, size, fill = "none", label, truncate = true) { - label = truncate ? truncateString(label, LABEL_MAX_CHARS) : label; - - let args = { - className: "legend-bar", - x: 0, - y: 0, - width: size, - height: "2px", - fill: fill, - }; - let text = createSVG("text", { - className: "legend-dataset-text", - x: 0, - y: 0, - dy: FONT_SIZE * 2 + "px", - "font-size": FONT_SIZE * 1.2 + "px", - "text-anchor": "start", - fill: FONT_FILL, - innerHTML: label, - }); - - let group = createSVG("g", { - transform: `translate(${x}, ${y})`, - }); - group.appendChild(createSVG("rect", args)); - group.appendChild(text); - - return group; -} - export function legendDot( x, y, @@ -346,9 +315,11 @@ export function legendDot( fill = "none", label, value, + font_size = null, truncate = false ) { label = truncate ? truncateString(label, LABEL_MAX_CHARS) : label; + if (!font_size) font_size = FONT_SIZE; let args = { className: "legend-dot", @@ -364,32 +335,38 @@ export function legendDot( className: "legend-dataset-label", x: size, y: 0, - dx: FONT_SIZE + "px", - dy: FONT_SIZE / 3 + "px", - "font-size": FONT_SIZE * 1.2 + "px", + dx: font_size + "px", + dy: font_size / 3 + "px", + "font-size": font_size * 1.6 + "px", "text-anchor": "start", fill: FONT_FILL, innerHTML: label, }); - let textValue = createSVG("text", { - className: "legend-dataset-value", - x: size, - y: FONT_SIZE + 10, - dx: FONT_SIZE + "px", - dy: FONT_SIZE / 3 + "px", - "font-size": FONT_SIZE * 1.2 + "px", - "text-anchor": "start", - fill: FONT_FILL, - innerHTML: value, - }); + let textValue = null; + if (value) { + textValue = createSVG("text", { + className: "legend-dataset-value", + x: size, + y: FONT_SIZE + 10, + dx: FONT_SIZE + "px", + dy: FONT_SIZE / 3 + "px", + "font-size": FONT_SIZE * 1.2 + "px", + "text-anchor": "start", + fill: FONT_FILL, + innerHTML: value, + }); + } let group = createSVG("g", { transform: `translate(${x}, ${y})`, }); group.appendChild(createSVG("rect", args)); group.appendChild(textLabel); - group.appendChild(textValue); + + if (value && textValue) { + group.appendChild(textValue); + } return group; }