Chartist-js: Chartist labels are getting cropped.

Created on 21 Jan 2015  路  7Comments  路  Source: gionkunz/chartist-js

Here's an example from my site:

screenshot 2015-01-22 05 46 11

This also happens on chartists documentation site (http://gionkunz.github.io/chartist-js/getting-started.html):

screenshot 2015-01-22 05 45 55

Is this expected behavior? The only way I can fix it is by manually adjusting the <foreignobject> but then the label overlays the graph, or set overflow: visible on <svg>.

Most helpful comment

Hey there. As the multiline labels are done with foreignObjects in SVG there is no way how we could assume a required width. For this purpose we switched to a configurable offset of the chart per axis. In the configuration just use the offset configuration if you need to expand the space used for the labels:

axisX: {
  offset: 100
},
axisY: {
  offset: 100
}

Check this example: http://jsbin.com/fesavu/1/edit?html,css,js,output

All 7 comments

Hey there. As the multiline labels are done with foreignObjects in SVG there is no way how we could assume a required width. For this purpose we switched to a configurable offset of the chart per axis. In the configuration just use the offset configuration if you need to expand the space used for the labels:

axisX: {
  offset: 100
},
axisY: {
  offset: 100
}

Check this example: http://jsbin.com/fesavu/1/edit?html,css,js,output

Thanks for the example.

Effectively the solution would need to:

  • Dynamically check the width after the chart is loaded since I my labels are free form from the users.
  • Dynamically re-check when the data changes, since there's some filtering options that updates the graph.
  • Dynamically re-check when the chart resizes and previously single-line labels become multi-line.

I don't mind doing the work, but it seems like something the charting library should be helping with since it would need to be solved anywhere chartists is used (apologies if this sounds inflammatory, it's not intended as such). Can't you render the labels first, measure foreignObject and then set the rest of the graph by default?

Measuring text width is very ugly as you need to use the clientRect which causes a reflow on access. We had big performance issues with that. I'd generally limit the amount of text that can be put into a label and use a static offset that allows enough space. Also increase the scaleMinSpace option to allow two lines of label text. This should allow you to have multi line labels that allow up to 30 characters depending on your font size.

Maybe we could also selectively re-introduce single line labels which calculate their offset using max width of pre-generated axis lables like we did before. This should be configurable on both axis individually.

I don't see this happening in the current architecture. If you really need to rely on dynamic label space, please calculate the text size outside of Chartist and update the config using chart.update. Don't get me wrong but I think there is just so many unclear things how to handle this and it does so much depend on the context. How many wrapped lines before you start to increase the width of a label? Whats the maximum you would expand? All these open design questions would also mean we create an opinionated solution. I think this should happen outside of chartist. This could be implemented in a plugin (maybe ctAutoOffset or something) which will add this functionality.

Hey there. As the multiline labels are done with foreignObjects in SVG there is no way how we could assume a required width. For this purpose we switched to a configurable offset of the chart per axis. In the configuration just use the offset configuration if you need to expand the space used for the labels:

axisX: {
  offset: 100
},
axisY: {
  offset: 100
}

Check this example: http://jsbin.com/fesavu/1/edit?html,css,js,output

Cool, This worked for me! Had to put these values in options of chart configuration like this:

barChart1: Chart = { type: 'Bar', data: { "labels": [], "series": [] }, options: { stackBars: true, axisY: { offset: 70 } }, events: { draw() { }

This is what worked for me.

svg.ct-chart-bar, svg.ct-chart-line{
    overflow: visible;
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ShlomoRosenheimer picture ShlomoRosenheimer  路  3Comments

Globegitter picture Globegitter  路  4Comments

ShlomoRosenheimer picture ShlomoRosenheimer  路  3Comments

andreasba picture andreasba  路  3Comments

adilbenmoussa picture adilbenmoussa  路  4Comments