Skip to content

Commit

Permalink
Multiline for labels (#34)
Browse files Browse the repository at this point in the history
* support multilines

* fix space

Co-authored-by: Nassim Masmoudi <nassim.masmoudi@energiency>
  • Loading branch information
nassissme and Nassim Masmoudi committed May 31, 2021
1 parent 52ddab7 commit afeddca
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 3 deletions.
42 changes: 39 additions & 3 deletions src/controller.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

import {DatasetController} from 'chart.js';
import {valueOrDefault} from 'chart.js/helpers';
import {valueOrDefault, isNullOrUndef} from 'chart.js/helpers';
import {layout} from './layout';

export function buildNodesFromFlows(data) {
Expand Down Expand Up @@ -163,7 +163,6 @@ export default class SankeyController extends DatasetController {

ctx.save();
const chartArea = me.chart.chartArea;

for (const node of nodes.values()) {
const x = xScale.getPixelForValue(node.x);
const y = yScale.getPixelForValue(node.y);
Expand All @@ -180,11 +179,48 @@ export default class SankeyController extends DatasetController {
ctx.textAlign = 'right';
textX -= borderWidth + 4;
}
ctx.fillText(label, textX, y + height / 2);
this._drawLabel(label, y, height, ctx, textX);
}
ctx.restore();
}

_drawLabel(label, y, height, ctx, textX) {
const lines = isNullOrUndef(label) ? [] : this.toTextLines(label);
const linesLength = lines.length;
const middle = y + height / 2;
const padding = 7.5;
const textHeight = 15;

if (linesLength > 1) {
const top = middle - (textHeight * linesLength / 2) + padding;
for (let i = 0; i < linesLength; i++) {
ctx.fillText(lines[i], textX, top + (i * textHeight));
}
} else {
ctx.fillText(label, textX, middle);
}
}

// @todo move this in Chart.helpers.toTextLines
toTextLines(inputs) {
var lines = [];
var input;

inputs = [].concat(inputs);
while (inputs.length) {
input = inputs.pop();
if (typeof input === 'string') {
lines.unshift.apply(lines, input.split('\n'));
} else if (Array.isArray(input)) {
inputs.push.apply(inputs, input);
} else if (!isNullOrUndef(inputs)) {
lines.unshift('' + input);
}
}

return lines;
}

_drawNodes() {
const me = this;
const ctx = me._ctx;
Expand Down
51 changes: 51 additions & 0 deletions test/fixtures/labels-multiline.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const data = [
{from: 'Oil', to: 'Fossil Fuels', flow: 100},
{from: 'Oil', to: 'Natural Gas', flow: 50},
{from: 'Natural Gas', to: 'Coal', flow: 50},
{from: 'Coal', to: 'Electricity', flow: 50},
{from: 'Fossil Fuels', to: 'Energy', flow: 100},
];

const colors = {
Oil: 'black',
Coal: 'gray',
'Fossil Fuels': 'slategray',
Electricity: 'blue',
Energy: 'orange'
};

const labels = {
'Natural Gas': 'Nat. gas \nsubtitle 1\nsubtitle 2',
'Fossil Fuels': 'Fossil\nsubtitle 1\nsubtitle 2',
Coal: 'Coal\nsubtitle 1\nsubtitle 2\nsubtitle 3\nsubtitle 4',
Energy: 'Energy\nsubtitle 1\nsubtitle 2\nsubtitle 3',
Electricity: 'Electricity\nsubtitle 1'
};

function getColor(name) {
return colors[name] || 'green';
}


module.exports = {
config: {
type: 'sankey',
data: {
datasets: [
{
data,
colorFrom: (c) => getColor(c.dataset.data[c.dataIndex].from),
colorTo: (c) => getColor(c.dataset.data[c.dataIndex].to),
labels,
}
]
}
},
options: {
spriteText: true,
canvas: {
height: 512,
width: 512
}
}
};
Binary file added test/fixtures/labels-multiline.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit afeddca

Please sign in to comment.