I have been tasked to implement zooming in custom charts based on SVGs. Before i had one <svg>
element. I looked into either using the transform
or the viewbox
approach and decided for the viewbox
approach. Since i have to support zooming on just the x-axis, the charts contents will be squashed depending on the zoomFactor
and need preserveAspectRatio="none"
. This does not look pretty for the chart labels that i used foreignObjects
for. They get disorted as well and are not readable anymore. I did not find any solutions on how to apply the viewbox
to just the actual chart contents, not the scales / labels.
I came up with the solution to split the chart into 3 nested svgs. The structure looks like this:
<svg> // Container SVG
<svg>...</svg> // XAxis
<svg>...</svg> // YAxis
<svg>...</svg> // ChartContent
</svg>
The viewbox
will only be applied to the ChartContent svg and the svgs with the actual scales stay untouched and are just simply rerendered if needed with different labels at different positions. The desired outcome is similar to this example: https://jsfiddle.net/19h83ker/1/
Given that i have a chart to display that is as an example 4000 pixels wide and 200 pixels high, the y-axis is 40 pixels wide and 200 pixels high, the x-axis is 40 pixels high and 4000 pixels wide, how should i generally setup the viewports? If i set width="100%"
and height="100%"
on the ContainerSVG and ChartContent SVG, i have no scrollbar available. If i set width="4040"
on the ContainerSVG and width="4000"
on the ChartContent SVG, i have a scrollbar but applying the viewbox
while zooming out by 100% will simply halve my svg in width and the right 50% are left blank. I dont really understand what the combination of widths / heights is in my structure, that i should be going for. Or am i making a mistake in general? Are there better ways to implement the desired outcome? I have already spent 2 days on this and dont really see any other option than these 3 nested svgs.At the end of the day panning / zooming in the 4000 pixel wide example SVG chart should be possible.