@Atrhick Thanks for asking and the proposed workaround. I finally gave up with CanvasJS, there seems to be some sort of compatibility issue with Vite or I am not skillful in React yet to debug what’s going on, so I’ve switched to another library that has better compatibility without Webpack or Browserify.
Cheers.
I am running into trouble with the proposed solution. As true as it is that the @ts-ignore macro allows React to compile, the compiled application retains some “require” instructions from the module that the browser cannot parse, thus returning Uncaught ReferenceError: require is not defined
. Here’s a fragment of the compiled application with a minified-then-beautified version of canvas.react.js:
var qN = require("react/jsx-runtime").jsx,
hc = require("react"),
i6 = require("@canvasjs/charts");
i6 = i6.Chart ? i6 : window.CanvasJS;
class $N extends hc.Component {
constructor(e) {
super(e), this.options = e.options ? e.options : {}, this.containerProps = e.containerProps ? N2({}, e.containerProps) : {
width: "100%",
position: "relative"
}, this.containerProps.height = e.containerProps && e.containerProps.height ? e.containerProps.height : this.options.height ? this.options.height + "px" : "400px", this.containerRef = hc.createRef()
}
componentDidMount() {
this.chart = new i6.Chart(this.containerRef.current, this.options), this.chart.render(), this.props.onRef && this.props.onRef(this.chart)
}
shouldComponentUpdate(e, c) {
return e.options !== this.options
}
componentDidUpdate() {
this.chart.options = this.props.options, this.chart.render()
}
componentWillUnmount() {
this.chart && this.chart.destroy(), this.props.onRef && this.props.onRef(void 0)
}
render() {
return qN("div", {
id: this.props.id,
ref: this.containerRef,
style: this.containerProps
})
}
}
I have tested the module using JSX, but for this project TypeScript is a must. What else can I do?
Regards.
Thank you so much, Adithya, it works like a charm!
Best regards.
Indranil,
I have hacked my way to get a working example using our customer’s data. I used the minified library for the old version they have in their website so please excuse me if the variable names don’t match the current ones in the most recent version.
Our starting point will be the function “E.prototype.createLabels”, which controls how the labels will be created. I will modify this block a bit (I have formatted it so I could know what the “for” was doing):
if ("axisX" === this.type && "dateTime" === this.chart.plotInfo.axisXValueType)
{
for (
this.intervalStartPosition = this.getLabelStartPoint(new Date(this.viewportMinimum), this.intervalType, this.interval),
d = taNew(this.viewportMaximum, this.interval, this.intervalType),
b = this.viewportMinimum;
b < d;
b = taNew(b, this.interval, this.intervalType)
)
{
a = b, a = this.labelFormatter ? this.labelFormatter({
chart: this.chart._publicChartReference,
axis: this._options,
value: b,
label: this.labels[b] ? this.labels[b] : null
}) : "axisX" === this.type && this.labels[a] ? this.labels[a] : ra(b, this.valueFormatString, this.chart._cultureInfo), a = new M(this.ctx, {
x: 0,
y: 0,
maxWidth: e,
maxHeight: g,
angle: this.labelAngle,
text: this.prefix + a + this.suffix,
horizontalAlign: "left",
fontSize: this.labelFontSize,
fontFamily: this.labelFontFamily,
fontWeight: this.labelFontWeight,
fontColor: this.labelFontColor,
fontStyle: this.labelFontStyle,
textBaseline: "middle"
}), this._labels.push({
position: b,
textBlock: a,
effectiveHeight: null
});
}
}
I am also calling a new function, “taNew”, which is not really optimal but will help us do the trick:
function taNew(a, c, b){
if ("millisecond" === b) return a + 1 * c;
if ("second" === b) return a + 1 * 1000 * c;
if ("minute" === b) return a + 1 * 1000 * 60 * c;
if ("hour" === b) return a + 1 * 1000 * 60 * 60 * c;
if ("day" === b) return a + 1 * 1000 * 60 * 60 * 24 * c;
if ("week" === b) return a + 1 * 1000 * 60 * 60 * 24 * 7 * c;
if ("month" === b) return a + 1 * 1000 * 60 * 60 * 24 * 30 * c;
if ("year" === b) return a + 1 * 1000 * 60 * 60 * 24 * 365 * c;
}
Please note that I am not creating Date objects in the process because I will leave this task to my own code when I create the chart. With these changes, the result is this:
We can see that axisX now has all the marks from 11PM to 4AM (I guess it shifts one second because my code is not perfect, but it is a real progress). Since I never use “new Date()” in the library the variables are integers representing timestamps and I leave the task to transform them into readable times to a custom function in labelFormatter. Thus, the axis is not “broken” anymore.
Hope this helps you debugging.
Regards.