Pre loader

Category: JavaScript

Welcome to the SciChart Forums!

  • Please read our Question Asking Guidelines for how to format a good question
  • Some reputation is required to post answers. Get up-voted to avoid the spam filter!
  • We welcome community answers and upvotes. Every Q&A improves SciChart for everyone

WPF Forums | JavaScript Forums | Android Forums | iOS Forums

0 votes
16k views

I want to build a column chart but I got the following error:

ERROR TypeError: Cannot read property ‘append’ of undefined

The error happened in line #42.

My code:

export class OutputAmplitudeComponent implements OnInit, OnDestroy {

constructor(@Inject(SETTING_SERVICE) private settingService: SettingService, private cdr: ChangeDetectorRef) {}

ngOnInit() {        
                this.settingService.registerSetting(HarmonicAmpSetting).pipe(takeUntil(this.ngUnsubHarmonicData)).subscribe(setting => {
                    const OutputAmplitudeData = setting.value;

                    for (let x = 1; x < this.numberOfOutput; x++) {
                        if (this.OutputMode === 'Voltage') {
                            if (phaseNum === 1) {
                                this.ampSource.data[x-1].voltage1 = OutputAmplitudeData[x];
                            } else if (phaseNum === 2) {
                                this.ampSource.data[x-1].voltage2 = OutputAmplitudeData[x];
                            } else if (phaseNum === 3) {
                                this.ampSource.data[x-1].voltage3 = OutputAmplitudeData[x]; 
                            }
                        } else if (this.OutputMode === 'Current') {
                            if (phaseNum === 1) {
                                this.ampSource.data[x-1].current1 = OutputAmplitudeData[x];
                            } else if (phaseNum === 2) {
                                this.ampSource.data[x-1].current2 = OutputAmplitudeData[x];
                            } else if (phaseNum === 3) {
                                this.ampSource.data[x-1].current3 = OutputAmplitudeData[x];
                            }
                        }

                    }   
                    this.updateData();
                });
                this.sciChartInit();
            }   

updateData(){
    var phaseNum1 = [];
    var xData = [];
    for (let x = 1; x < this.numberOfOutput; x++) {
        if (this.ampSource.data != null && this.ampSource.data[x-1] != null) {
            phaseNum1[x - 1] = parseFloat(this.ampSource.data[x - 1].voltage1);
            xData[x - 1] = x;
            if (!isNaN(phaseNum1[x - 1])) {
                this.dataSeries1.append(x,x);
            } else {
                console.log("No num");
            }
        }
    }
}       

async sciChartInit() {

    const { wasmContext, sciChartSurface } = await SciChartSurface.create("chart");

    var phaseNum1 = [];
    var xData = [];
    this.dataSeries1 = new XyDataSeries(wasmContext);
    for (let x = 1; x < this.numberOfOutput; x++) {
        this.dataSeries1.append(x, x);
    }

    const xAxis = new NumericAxis(wasmContext);
    sciChartSurface.xAxes.add(xAxis);
    const yAxis = new NumericAxis(wasmContext);
    sciChartSurface.yAxes.add(yAxis);

    const rendSeries1 = new StackedColumnRenderableSeries(wasmContext);
    rendSeries1.fill = "#dc443f";
    rendSeries1.stroke = "green";
    rendSeries1.strokeThickness = 1;
    rendSeries1.dataSeries = this.dataSeries1;
    rendSeries1.stackedGroupId = "one";

    const verticallyStackedColumnCollection = new StackedColumnCollection(wasmContext);
    verticallyStackedColumnCollection.dataPointWidth = 0.5;
    verticallyStackedColumnCollection.add(rendSeries1);
    verticallyStackedColumnCollection.animation = new ScaleAnimation({ duration: 1000, fadeEffect: true });

    sciChartSurface.renderableSeries.add(verticallyStackedColumnCollection);
    sciChartSurface.chartModifiers.add(new ZoomExtentsModifier(), new ZoomPanModifier(), new MouseWheelZoomModifier());
    sciChartSurface.zoomExtents();

    sciChartSurface.chartModifiers.add(
        new LegendModifier({
            placement: ELegendPlacement.TopRight,
            orientation: ELegendOrientation.Horizontal,
            showLegend: true,
            showCheckboxes: true,
            showSeriesMarkers: true
        })
    );
    return { wasmContext, sciChartSurface };
}}

I don’t understand what is undefined and why.

Thank you.

  • ETS Ong asked 3 years ago
  • last active 3 years ago
0 votes
12k views

paletteProvider transparent colour is not working.

I tried with parseColorToUIntArgb(“#ffffff00”) and parseColorToUIntArgb(“#ffffff00”, 0) to replace the colour with transparent. But its not working.

I want ho hide the marker on the chart if the value is less than a limit. Is any other possibility to hide the marker based on value?
can you check the image, i want to show only the yellow marker.
one more error i am getting from typescript
“Type ‘undefined’ is not assignable to type ‘TPointMarkerArgb'”.

0 votes
12k views

I see in the documentation that I need to set the boolean to true/false. But my question is how do I do this after the series has been rendered? I am using a custom legend and need to be able to toggle visibility.

  export default function Chart() {
  const [sciChartSurface, setSciChartSurface] = React.useState<SciChartSurface>();
  const [wasmContext, setWasmContext] = React.useState<TSciChart>();

  const dataSeriesMapRef = React.useRef<Map<keyof typeof chartData, XyDataSeries>>();

  React.useEffect(() => {
    (async () => {
      const { sciChartSurface, wasmContext } = await drawChart(theme, chartType);
      setSciChartSurface(sciChartSurface);
      setWasmContext(wasmContext);
    })();

    dataSeriesMapRef.current = new Map<keyof typeof chartData, XyDataSeries>();

    return () => sciChartSurface?.delete();
  }, [chartType]); // make sure the chart is initialized only once

  React.useEffect(() => {
    if (dataSeriesMapRef.current && sciChartSurface && wasmContext && !isLoading) {
      // const currentSeries = sciChartSurface.renderableSeries.asArray();
      // if (currentSeries) sciChartSurface.renderableSeries.clear();
      updateChartWithData(dataSeriesMapRef.current, theme, wasmContext, sciChartSurface, chartData, chartType);
    }
  }, [theme, chartData, wasmContext, sciChartSurface, isLoading]);

  return (
    <div id="chart-container">
      <ControlsLegend
        chartData={chartData}
        dataSeriesMap={dataSeriesMapRef.current as Map<keyof typeof chartData, XyDataSeries>}
        theme={theme}
        sciChartSurface={sciChartSurface as SciChartSurface}
        wasmContext={wasmContext as TSciChart}
      />
      <div id={DIVID} style={{ width: windowWidth, height: windowHeight }} />
      <ControlsBottom />
    </div>
  );
}

drawChart.js

    export default async (theme: ExtendedTheme, chartType: string) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(DIVID);
  const isLightTheme = theme.palette.type === 'light';

  console.log('createChart');
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);

  xAxis.labelProvider.formatLabel = (unixTimestamp: number) => {
    return new Date(unixTimestamp * 1000).toLocaleDateString('en-us', {
      month: 'short',
      year: 'numeric',
      day: 'numeric',
    });
  };

  yAxis.labelProvider = new CustomLabelProvider();

  sciChartSurface.yAxes.add(yAxis);
  sciChartSurface.xAxes.add(xAxis);

  if (chartType !== 'stack') sciChartSurface.chartModifiers.add(new RolloverModifier({ showRolloverLine: false }));
  sciChartSurface.chartModifiers.add(new ZoomPanModifier());
  sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());
  sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
  sciChartSurface.chartModifiers.add(new PinchZoomModifier());

  const rubberBandXyZoomModifier = new RubberBandXyZoomModifier({
    isAnimated: true,
    animationDuration: 400,
    easingFunction: easing.outExpo,
    fill: '#FFFFFF33',
    stroke: '#FFFFFF77',
    strokeThickness: 1,
  });
  sciChartSurface.chartModifiers.add(rubberBandXyZoomModifier);

  sciChartSurface.zoomExtents();

  if (isLightTheme) sciChartSurface.applyTheme(new SciChartJSLightTheme());
  else sciChartSurface.applyTheme(new SciChartJSDarkTheme());
  return { sciChartSurface, wasmContext };
};

updateChartWithData.js

    export const updateChartWithData = (
  dataSeriesMap: Map<keyof typeof chartData, XyDataSeries>,
  theme: ExtendedTheme,
  wasmContext: TSciChart,
  sciChartSurface: SciChartSurface,
  chartData: ChartData,
  chartType: string
) => {
  sciChartSurface.invalidateElement();
  const streamIds = Object.keys(chartData);
  const isLightTheme = theme.palette.type === 'light';

  if (isLightTheme) sciChartSurface.applyTheme(new SciChartJSLightTheme());
  else sciChartSurface.applyTheme(new SciChartJSDarkTheme());

  sciChartSurface.invalidateElement();
  console.log('updateChartWithData');
  console.log(chartData);

  const stackedColumns: any[] = [];
  streamIds.forEach((s) => {
    const streamId = Number(s) as keyof ChartData;
    const streamSelectorId = streamId as keyof typeof chartData;
    if (dataSeriesMap.has(streamSelectorId)) {
      const xyDataSeries = dataSeriesMap.get(streamSelectorId);
      chartData[streamId].data.forEach((value) => {
        xyDataSeries?.append(value.timestamp, value.value);
      });
    } else if (chartType === 'scatter') {
      const lineSeries = LineChart(dataSeriesMap, theme, wasmContext, chartData, streamSelectorId, streamId);

      sciChartSurface.renderableSeries.add(lineSeries);
      sciChartSurface.zoomExtents();
    } else if (chartType === 'bar') {
      const lineSeries = BarChart(dataSeriesMap, theme, wasmContext, chartData, streamSelectorId, streamId);
      sciChartSurface.renderableSeries.add(lineSeries);
      sciChartSurface.zoomExtents();
    } else {
      const lineSeries = StackedChart(dataSeriesMap, theme, wasmContext, chartData, streamSelectorId, streamId);
      stackedColumns.push(lineSeries);
    }
  });
};

“LineChart.js”

    export default (
  dataSeriesMap: Map<keyof typeof chartData, XyDataSeries>,
  theme: ExtendedTheme,
  wasmContext: TSciChart,
  chartData: ChartData,
  streamSelectorId: keyof typeof chartData,
  streamId: keyof ChartData
) => {
  const xyDataSeries = new XyDataSeries(wasmContext);
  dataSeriesMap.set(streamSelectorId, xyDataSeries);

  const obj = chartData[streamSelectorId];
  const stroke = obj.stroke as string;
  xyDataSeries.dataSeriesName = obj.label as string;

  chartData[streamId].data.forEach((value) => {
    xyDataSeries.append(value.timestamp, value.value);
  });

  const lineSeries = new FastLineRenderableSeries(wasmContext, {
    stroke,
    strokeThickness: obj.strokeThickness,
    strokeDashArray: obj.strokeDashArray,
    dataSeries: xyDataSeries,
    animation: new WaveAnimation({ zeroLine: -1, pointDurationFraction: 0.5, duration: 1000 }),
  });

  lineSeries.rolloverModifierProps.tooltipColor = theme.palette.background.paper;
  lineSeries.rolloverModifierProps.tooltipTextColor = theme.palette.getContrastText(stroke);
  lineSeries.rolloverModifierProps.markerColor = stroke;
  lineSeries.rolloverModifierProps.tooltipTemplate = (
    id: string,
    tooltipProps: RolloverModifierRenderableSeriesProps,
    seriesInfo: SeriesInfo,
    updateSize: (width: number, height: number) => void
  ) => {
    const { tooltipColor, tooltipTextColor, markerColor } = tooltipProps;
    const { formattedXValue, yValue, seriesName } = seriesInfo;
    const width = 192;
    const height = 60;

    updateSize(width, height);
    return `<svg width='${width}' height='${height}' class="root">
        <rect width="100%" height="100%" fill='${tooltipColor}' stroke='${markerColor}' stroke-width='2' />
         <svg width='100%'>
           <text dy="0" fill='${tooltipTextColor}'>
            <tspan x="15" y="20" class="title">${formattedXValue}</tspan>
             <tspan x="15" y="45" class="value">
              ${seriesName} | ${yValue.toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
             </tspan>
          </text>
        </svg>
      </svg>`;
  };
  return lineSeries;
};

lengend.js

    let _chartData: any[] = [];
export default ({
  dataSeriesMap,
  theme,
  wasmContext,
  sciChartSurface,
  chartData,
}: {
  dataSeriesMap: Map<keyof typeof chartData, XyDataSeries>;
  theme: ExtendedTheme;
  wasmContext: TSciChart;
  sciChartSurface: SciChartSurface;
  chartData: ChartData;
}) => {
  const classes = useStyles();

  const chartRef = React.useRef<any>([]);
  const [legendData, setLegendData] = React.useState<any[]>([]);

  // _chartData = [..._chartData, ...values(chartData)];
  _chartData = values(chartData);
  _chartData = uniqby(_chartData, 'groupId');
  _chartData = uniqby(_chartData, 'streamId');

  React.useEffect(() => {
    if (_chartData.length > 0 && !isEqual(chartRef.current, _chartData)) {
      setLegendData(_chartData);
      chartRef.current = _chartData;
    }
  }, [_chartData]);

  const onClick = React.useCallback(
    (item) => {
      // const xyDataSeries = dataSeriesMap.get(160);
      const _legendData = legendData.map((x) => {
        if (x.groupId === item.groupId) x.isVisible = !x.isVisible;
        return x;
      });

      setLegendData(_legendData);
    },
    [legendData]
  );

  return (
    <div className={classes.root}>
      <Paper variant="outlined" square>
        {legendData.map((item: any) => (
          <div className={classes.listItem} key={item.streamId}>
            <IconButton
              onClick={() => onClick(item)}
              style={{ color: item.stroke }}
              size="small"
              aria-label={item.label}
            >
              {item.isVisible ? <VisibilityIcon /> : <VisibilityOffIcon />}
            </IconButton>
            <div>{item.label}</div>
          </div>
        ))}
      </Paper>
    </div>
  );
};

Inside the onClick function is where I was trying to change visibility for both series. I’ve tried multiple things without any luck. I assumed it would be as simple as getting the correct series, setting the visible property and maybe a re-render if that is even needed? Like I said any advice on a better way of handling this is welcome

0 votes
12k views

I want to build a Stacked Column Side by Side Chart by referring to the reference here.

However, the program could not enter line #41. It just stuck there and the column chart could not be shown.

My code:

export class OutputAmplitudeComponent implements OnInit, OnDestroy {

constructor(@Inject(SETTING_SERVICE) private settingService: SettingService, private cdr: ChangeDetectorRef) {}

ngOnInit() {        
                this.settingService.registerSetting(HarmonicAmpSetting).pipe(takeUntil(this.ngUnsubHarmonicData)).subscribe(setting => {
                    const OutputAmplitudeData = setting.value;

                    for (let x = 1; x < this.numberOfOutput; x++) {
                        if (this.OutputMode === 'Voltage') {
                            if (phaseNum === 1) {
                                this.ampSource.data[x-1].voltage1 = OutputAmplitudeData[x];
                            } else if (phaseNum === 2) {
                                this.ampSource.data[x-1].voltage2 = OutputAmplitudeData[x];
                            } else if (phaseNum === 3) {
                                this.ampSource.data[x-1].voltage3 = OutputAmplitudeData[x]; 
                            }
                        } else if (this.OutputMode === 'Current') {
                            if (phaseNum === 1) {
                                this.ampSource.data[x-1].current1 = OutputAmplitudeData[x];
                            } else if (phaseNum === 2) {
                                this.ampSource.data[x-1].current2 = OutputAmplitudeData[x];
                            } else if (phaseNum === 3) {
                                this.ampSource.data[x-1].current3 = OutputAmplitudeData[x];
                            }
                        }
                        this.sciChartInit(x);
                    }   
                });
            }   


async sciChartInit(x:number) {

    var phase1 = parseFloat(this.ampSource.data[x-1].voltage1);
    var phase2 = parseFloat(this.ampSource.data[x-1].voltage2);
    var phase3 = parseFloat(this.ampSource.data[x-1].voltage3);

    //stuck here

    const { wasmContext, sciChartSurface } = await SciChartSurface.create("chart");

    const xAxis = new NumericAxis(wasmContext);
    sciChartSurface.xAxes.add(xAxis);
    const yAxis = new NumericAxis(wasmContext);
    sciChartSurface.yAxes.add(yAxis);

    const dataSeries1 = new XyDataSeries(wasmContext, { xValues:[x], yValues:[phase1], dataSeriesName: "Phase 1" });
    const dataSeries2 = new XyDataSeries(wasmContext, { xValues:[x], yValues:[phase2], dataSeriesName: "Phase 2" });
    const dataSeries3 = new XyDataSeries(wasmContext, { xValues:[x], yValues:[phase3], dataSeriesName: "Phase 3" });

    const rendSeries1 = new StackedColumnRenderableSeries(wasmContext);
    rendSeries1.fill = "#dc443f";
    rendSeries1.stroke = "black";
    rendSeries1.strokeThickness = 1;
    rendSeries1.dataSeries = dataSeries1;
    rendSeries1.rolloverModifierProps.markerColor = "#b83735";
    rendSeries1.rolloverModifierProps.tooltipColor = "#dc443f";
    rendSeries1.rolloverModifierProps.tooltipTextColor = "#fff";
    rendSeries1.stackedGroupId = "one";

    const rendSeries2 = new StackedColumnRenderableSeries(wasmContext);
    rendSeries2.fill = "#aad34f";
    rendSeries2.stroke = "black";
    rendSeries2.strokeThickness = 1;
    rendSeries2.dataSeries = dataSeries2;
    rendSeries2.rolloverModifierProps.markerColor = "#87a73e";
    rendSeries2.rolloverModifierProps.tooltipColor = "#aad34f";
    rendSeries2.rolloverModifierProps.tooltipTextColor = "#000";
    rendSeries2.stackedGroupId = "two";

    const rendSeries3 = new StackedColumnRenderableSeries(wasmContext);
    rendSeries3.fill = "#8562b4";
    rendSeries3.stroke = "black";
    rendSeries3.strokeThickness = 1;
    rendSeries3.dataSeries = dataSeries3;
    rendSeries3.rolloverModifierProps.markerColor = "#715195";
    rendSeries3.rolloverModifierProps.tooltipColor = "#8562b4";
    rendSeries3.rolloverModifierProps.tooltipTextColor = "#fff";
    rendSeries3.stackedGroupId = "three";

    const verticallyStackedColumnCollection = new StackedColumnCollection(wasmContext);
    verticallyStackedColumnCollection.dataPointWidth = 0.5;
    verticallyStackedColumnCollection.add(rendSeries1, rendSeries2, rendSeries3);
    verticallyStackedColumnCollection.animation = new ScaleAnimation({ duration: 1000, fadeEffect: true });

    sciChartSurface.renderableSeries.add(verticallyStackedColumnCollection);

    sciChartSurface.chartModifiers.add(new ZoomExtentsModifier(), new ZoomPanModifier(), new MouseWheelZoomModifier());

    sciChartSurface.zoomExtents();

    sciChartSurface.chartModifiers.add(new RolloverModifier({ rolloverLineStroke: "#228B22" }));
    sciChartSurface.chartModifiers.add(
        new LegendModifier({
            placement: ELegendPlacement.TopRight,
            orientation: ELegendOrientation.Horizontal,
            showLegend: true,
            showCheckboxes: true,
            showSeriesMarkers: true
        })
    );
    return { wasmContext, sciChartSurface };
} }

.
.
The data needed in the chart is identified and no error is shown.
Any idea on the solution?

Thank you.

  • ETS Ong asked 3 years ago
  • last active 3 years ago
1 vote
12k views

Hi, I want to color the axis label by its value,

eg.
value < 0 -> show red color
value = 0 -> show gray color
value > 0 -> show green color

similar to this question, but in javascript platform, it seems the LabelProvider has function related to the value(string) formatting only. Is there any ways to styling the label? Thanks!

0 votes
11k views

Scenario: user selects an area of a heatmap chart using a box annotation via a mouse drag.

I have created a custom modifier to draw the box annotation. I’ve used this as the basis: SimpleDataPointSelectionModifier.ts

My question is: how to I get the X axis start + end values and the Y axis start + end values based on the area of the annotation/mouse coordinates.

Thanks

0 votes
9k views

Some users have reported an error when importing SciChart.js into a TypeScript or JavaScript application:

TS1261: Already included file name ‘C:...\SciChartSurface.d.ts’ differs from file name ‘C:/…/node_modules/scichart/charting/
Visuals/Axis/SciChartSurface.d.ts’ only in casing.

Solution below…

1 vote
9k views

Hello,

I am trying out SciCharts and am looking to recreate the example 3D uniform surface mesh chart example and don’t have a good hold on the architecture yet. I don’t see directions as to which file to paste the example code into. I’m looking at the code example where it creates a “final camera3D camera – schiChart3DBuilder.newCamera3D().build();” and goes from there. (…/webframe.html#The%20Surface%20Mesh%203E%20Chart%20Type.html)

I have the 3D surface created and rendering. I just need to get started to go from there. Thank you.

1 vote
9k views

Hello,
How can I animate an update of a candle or a bar in an OHLC type charts? I use realtime stock chart like this example.
When i update candle it redraws immediately with new values. But i want it to be updated with animation.

  • Vita Bubko asked 3 years ago
  • last active 2 years ago
1 vote
8k views

From what I’ve read into chrome’s roadmap, everything seems on track for a webgpu release in May.
Is scichart taking this into account and planning to add webgpu support?
I suspect this would make quite an impact on performance, so it would be a great addition.

Thanks!

0 votes
8k views

I want to use my custom image as a background for SciChart js.
I tried to put background-image to body of the page.
Then I enabled transparent background via:

sciChartSurface.backgroundCompletelyTransparentEnabled = true;

But it doesn’t work. It does nothing.
Then I tried to put transparent background to SciChart:

sciChartSurface.background = "#00000000";

But it doesn’t work as well. Chart completely disappears in this case.

How can I put my image as a background for SciChart?

  • Roman Zye asked 2 years ago
  • last active 2 years ago
1 vote
8k views

Hello, I just started evaluating your 2D JS chart library and am running into an error (below) and don’t know what I should do to continue forward:

Error:

wasm streaming compile failed: TypeError: Failed to execute ‘compile’
on ‘WebAssembly’: Incorrect response MIME type. Expected
‘application/wasm’.

falling back to ArrayBuffer instantiation

failed to asynchronously prepare wasm: CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0

CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0

Could not load SciChart WebAssembly module.
Check your build process and ensure that your scichart2d.wasm, scichart2d.data and scichart2d.js files are from the same version

Uncaught (in promise) Could not load SciChart WebAssembly module.
Check your build process and ensure that your scichart2d.wasm, scichart2d.data and scichart2d.js files are from the same version


I am copying the scichart2d.data and scichart2d.wasm in my webpack config as follows (according to your tutorials):

config.plugins.push(
    new CopyPlugin({
        patterns: [
            // {
            //     from: 'src/index.html',
            //     to: '',
            // },
            {
                from: 'node_modules/scichart/_wasm/scichart2d.data',
                to: '',
            },
            {
                from: 'node_modules/scichart/_wasm/scichart2d.wasm',
                to: '',
            },
        ],
    })

I have since then done the following but to no avail:

  1. Restart my webpack-dev-server -> In chrome, “Empty cache and refresh”
  2. Delete my node_modules folder -> yarn install -> yarn start

Can someone please help me with this issue at an earliest convenience.

1 vote
8k views

Hi,

In past versions of SciChart JS I was able to run a webpack-built set of static files on an Nginx-based Docker container without issues.

I’m now seeing the error “memory access out of bounds” (screenshot attached) when doing this, and as a result does not render the charts at all, whether it’s running locally or hosted on AWS. This happens in both Chrome and Firefox.

It runs absolutely fine using webpack dev server.

The error seems to be coming from scichart2d.wasm. Any ideas?

Thanks
Joe

0 votes
8k views
  1. Big Sur 11.6.
  2. Monterey 12.2.1
  3. Catalina 10.15.7 (late 2013 model)
    ![enter image description here][1]

sciChart version 1.4.1611

If you open the chart in the Firefox browser, then, strangely enough, everything works.

Is it related to the version of the library?

1 vote
8k views

Hello,

We are working on our Angular Dashboard again using the JS Chart component and one item we would like to tidy up is the Meta Data displayed in the Tool Tips against data points.

When the cursor is enabled and a data point is hovered over, tool tips with the meta data is displayed for all data points in the vertical line; please refer to the screenshot attached.

We would like the tool tip to only be shown when the cursor is on a specific data point. We are currently working with an offshore team and any help surrounding this would be appreciated.

Kind regards,

1 vote
8k views

I have a chart that allow users to add one BoxAnnotation and multiple CustomAnnotation (a marker). I got error and failed to drag the BoxAnnotation with the following steps:

Step 1: Call the addMarkerAnnotation() to add a CustomAnnotation

const markerSvgString = '<svg height="26" width="18" xmlns="http://www.w3.org/2000/svg">' +
    '<polygon id="SVG_ID" fill="#000" fill-opacity="0.5" stroke="#00fc00" stroke-width="1.5" points="0,12 8,0 16,12 8,24" clip-path="url(#clip_normal)" />' +
    '<clipPath id="clip_normal"><use xlink:href="#SVG_ID"/></clipPath>' +
    '<text x="5" y="16" fill="#00fc00" font-weight="bold" font-size = "12">MARKER_ID</text>' +
'</svg>';

const deltaSvgString = '<svg height="28" width="28" xmlns="http://www.w3.org/2000/svg">' +
    '<polygon id="SVG_ID" fill="#000" fill-opacity="0.5" stroke="#00fc00" stroke-width="1.5" points="0,0 12,24 22,0" clip-path="url(#clip_delta)" />' +
    '<clipPath id="clip_delta"><use xlink:href="#SVG_ID"/></clipPath>' +
    '<text x="5" y="10" fill="#00fc00" font-weight="bold" font-size="10">MARKER_ID</text>' +
'</svg>';

const addMarkerAnnotation = useCallback((markerId, mode, x1, y1) => {   
    x1 = parseFloat(x1);
    y1 = parseFloat(y1);

    if (x1 != null && y1 != null) {
        let svgString;
        const svgId = "markerSvg_" + markerId;

        if (mode.includes("Delta")) {
            const compareMarkerKey = mode.replace("Delta ", "");
            svgString = deltaSvgString.replace(/MARKER_ID/g, (parseInt(markerId)+1) + "-" + compareMarkerKey);
        } else {
            svgString = markerSvgString.replace(/MARKER_ID/g, parseInt(markerId)+1);
        }
        svgString = svgString.replace(/SVG_ID/g, svgId);

        markerAnnotations.current[markerId] = new CustomAnnotation({
            x1,
            y1,
            id: markerId,
            isEditable: true,
            isSelected: true,
            verticalAnchorPoint: EVerticalAnchorPoint.Center,
            horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
            svgString: svgString
        });
        sciChartSurfaceRef.current.annotations.add(markerAnnotations.current[markerId]);
        reorderMarkers(markerId);

        markerAnnotations.current[markerId].dragEnded.handlers.push(() => {
            let annotation = markerAnnotations.current[markerId];
            let freq = annotation.x1 * FREQ_UNITS.KHZ;

            markersInfoSetter.current[markerId](origMarkerInfo => ({...origMarkerInfo, ...{freq: freq.toFixed(numDP.FREQ), power: annotation.y1.toFixed(numDP.POWER)}}));

            if (markersInfoObj.current[markerId].mode !== "Fixed") {
                getMarkerPeak(markerId, markersInfoObj.current[markerId].trace, annotation.x1 * FREQ_UNITS.GHZ);
            }
            reorderMarkers(markerId);
        });
    }
}, [deltaSvgString, markerSvgString, getMarkerPeak, reorderMarkers, numDP]);

Step 2: Call the removeMarkerAnnotation() to remove the CustomAnnotation

const removeMarkerAnnotation = useCallback((markerId) => {
    if (markerAnnotations.current[markerId]) {
        sciChartSurfaceRef.current.annotations.remove(markerAnnotations.current[markerId]);
        markerAnnotations.current[markerId].delete();
        markerAnnotations.current[markerId] = null;
    }
}, []);

Step 3: Call addTriggerAnnotation() to add a BoxAnnotation

const addTriggerAnnotation = useCallback((x1, x2, y2) => {
    x1 = parseFloat(x1);
    x2 = parseFloat(x2);    
    y2 = parseFloat(y2);

    if (x1 != null && x2 != null) {
        console.log("addTriggerAnnotation: ", x1, x2, triggerAnnotation.current, sciChartSurfaceRef.current.annotations);
        if (!triggerAnnotation.current) {
            triggerAnnotation.current = new BoxAnnotation({
                id: "triggerBox",
                fill: "transparent",
                stroke: "#93A3B1",  //#93A3B1   //#6B818C
                strokeThickness: 2,
                xCoordinateMode: ECoordinateMode.DataValue,
                x1: x1,
                x2: x2,
                yCoordinateMode: ECoordinateMode.DataValue,
                y1: minY,
                y2: y2,
                isEditable: true,
                resizeDirections: EXyDirection.XyDirection,     
            });
            sciChartSurfaceRef.current.annotations.add(triggerAnnotation.current);

            triggerAnnotation.current.dragDelta.handlers.push(() => {
                triggerAnnotation.current.y1 = minY;

                const minX =  specSettingsRef.current.start/freqUnits.KHZ;
                const maxX = specSettingsRef.current.stop/freqUnits.KHZ;
                const maxY = specSettingsRef.current.refLevel;

                if (minX != null && maxX != null) {
                    if (triggerAnnotation.current.x1 < minX) {
                        triggerAnnotation.current.x1 = minX;
                    } else if (triggerAnnotation.current.x1 > maxX) {
                        triggerAnnotation.current.x1 = maxX;
                    } else if (triggerAnnotation.current.x2 > maxX) {
                        triggerAnnotation.current.x2 = maxX;
                    } else if (triggerAnnotation.current.x2 < minX) {
                        triggerAnnotation.current.x2 = minX;
                    }
                }

                if (maxY != null) {
                    if (triggerAnnotation.current.y2 < minY) {
                        triggerAnnotation.current.y2 = minY;
                    } else if (triggerAnnotation.current.y2 > maxY) {
                        triggerAnnotation.current.y2 = maxY;
                    }
                }
            });

            triggerAnnotation.current.dragEnded.handlers.push(() => {
                const maxX = specSettingsRef.current.stop/freqUnits.KHZ;
                const x1 = triggerAnnotation.current.x1;
                const x2 = triggerAnnotation.current.x2;
                const y2 = triggerAnnotation.current.y2;

                if (x1 != null && x2 != null && maxX != null) {
                    if (x1 > x2) {
                        triggerAnnotation.current.x1 = x2;
                        triggerAnnotation.current.x2 = x1;
                    } else if (x2 < x1) {
                        triggerAnnotation.current.x1 = x2;
                        triggerAnnotation.current.x2 = x1;
                    } else if (x1 === x2) {
                        if (x2 + xInterval.current <= maxX) {
                            triggerAnnotation.current.x2 = x2 + xInterval.current;
                        } else {
                            triggerAnnotation.current.x1  = x1 - xInterval.current;
                        }
                    }

                    const origStartFreq = parseFloat(triggersRef.current.startFreq);
                    const origStopFreq = parseFloat(triggersRef.current.stopFreq);
                    const newStartFreq = parseFloat((triggerAnnotation.current.x1 * freqUnits.KHZ).toFixed(numDP.FREQ));
                    const newStopFreq = parseFloat((triggerAnnotation.current.x2 * freqUnits.KHZ).toFixed(numDP.FREQ));

                    if (origStartFreq !== newStartFreq || origStopFreq !== newStopFreq) {
                        setTriggers(origObj => ({...origObj, ...{
                            startFreq: newStartFreq, 
                            stopFreq: newStopFreq,
                            level: parseFloat(y2.toFixed(numDP.POWER)),
                        }}));
                    }
                }
            });
        } else {
            updateTriggerAnnotation(x1, x2, y2);
        }
    }
}, [setTriggers, freqUnits.KHZ, numDP.FREQ, numDP.POWER, minY, updateTriggerAnnotation]);

Step 4: Drag the BoxAnnotation. It’s failed to drag the box and got the error “Uncaught TypeError: Cannot read properties of undefined (reading ‘seriesViewRect’)”.

It’s a strange bug as it can only be reproduced with the steps above. With the following steps, I can drag the BoxAnnoation without problem:

Step 1 -> Step 3 -> Step 4
Step 3 -> Step 4
Step 3 -> Step 1 -> Step 2 -> Step 4

  • Quyen Sy asked 1 year ago
  • last active 1 year ago
0 votes
8k views

I am using NextJS with the SciChart trial license for development and suddenly got the error “SciChart: WebGL not supported! ” with Chrome. It worked fine before, and I didn’t change any codes for launching the chart. Also, it works fine with Firefox. The chrome version I am using is 107.0.5304.107.

BTW, the error is gone after I restarted my computer. Is it possible to be related to memory issue?

Below are my codes for initializing the chart:

  const initSciChart = () => {   
    // LICENSING //
           SciChartSurface.setRuntimeLicenseKey("xxx");

           SciChartDefaults.enableResampling = true;
    SciChartDefaults.asyncLabels = true;
    SciChartDefaults.useSharedCache = true;

    drawSpecChart();
};

async function drawSpecChart() {
    // Create the SciChartSurface in the div 'scichart-root'
    // The SciChartSurface, and webassembly context 'wasmContext' are paired. This wasmContext
    // instance must be passed to other types that exist on the same surface.

    let xAxesNumberRange = new NumberRange(0, 18);
    let yAxesNumberRange = new NumberRange(-140, -40);

    const chartDefinition = {
        xAxes: [{
            type: EAxisType.NumericAxis,
            options: {
                axisTitle: "Frequency (GHz)",
                axisTitleStyle: {
                    fontSize: 12,
                    fontFamily: "sans-serif",
                    fontWeight: "bold"
                },
                labelStyle: {
                    fontSize: 12,
                    fontFamily: "sans-serif"
                },
                visibleRange: xAxesNumberRange,
                zoomExtentsRange: xAxesNumberRange,
                labelFormat: ENumericFormat.Decimal,
                labelPrecision: 6,
                cursorLabelFormat: ENumericFormat.Decimal,
                cursorLabelPrecision: 6,
                drawMajorBands: false,
            }
        }],
        yAxes: [{
            type: EAxisType.NumericAxis,
            options: {
                axisTitle: "Power (dBm)",
                axisTitleStyle: {
                    fontSize: 12,
                    fontFamily: "sans-serif",
                    fontWeight: "bold"
                },
                labelStyle: {
                    fontSize: 12,
                    fontFamily: "sans-serif"
                },
                autoTicks: false,
                majorDelta: 10,
                minorDelta: 5,
                axisAlignment: EAxisAlignment.Left,
                visibleRange: yAxesNumberRange,
                zoomExtentsRange: yAxesNumberRange,
                labelFormat: ENumericFormat.Decimal,
                labelPrecision: 2,
                cursorLabelFormat: ENumericFormat.Decimal,
                cursorLabelPrecision: 2,
                drawMajorBands: false,
            },
        }],
        series: [],
        modifiers: [
            { type: EChart2DModifierType.MouseWheelZoom },
            { 
                type: EChart2DModifierType.ZoomExtents,
                options: {
                    isAnimated: false
                }
            }
        ]
           };

       const { sciChartSurface, wasmContext } = await chartBuilder.build2DChart("scichart-root", chartDefinition);  

    xAxesNumberRange = null;
    yAxesNumberRange = null;
};
1 vote
8k views

Hello,

I have a BlazorWASM app. I am wondering how to sync the x values of different renderable series that have different number of data points.

In a simple form, I am passing in the data for a moving average to be rendered on the chart that has already been populated with data. The moving average data has already been calculated and has the correct date timestamps. But when I add this series to the chart it is starting at index 0 of where the the price data started instead of where the xAxis date of this renderable series has.

I prefer not to use the filters api to regenerate this data as some will be complex and have already been calculated by study or pulled from a database. I have seen the article to offset a series but this seems unnecessary since I already have the x axis coordinate that I want each point of the new line series to be rendered.

Is there somewhere in the docs that I missed how to get these renderable series to line up properly to their own x data points?

Thank you

  • Leland asked 2 years ago
  • last active 2 years ago
0 votes
8k views

I am trying to implement a waterfall chart with uniform heatmap. The data is updated from the top of the chart and keeps pushing the old data down. I would like to show the y-axis with time. How can I update the y-axis with updated data?

Assume the heatmap is 256 height, I created the zValues array with min value when draw the heatmap:

const SPECTROGRAM_WIDTH = 256; 
const minPower = -200;
spectrogramZValues.current = Array.from(Array(SPECTROGRAM_HEIGHT), () => Array(SPECTROGRAM_WIDTH).fill(minPower));

Update zValues array when new data come:

    spectrogramZValues.current.shift();
        spectrogramZValues.current.push(newData);

When the first data pushed to the chart. There will be one row shown in the axis with timestamp t1. When the second data comes, the top row of the y-axis should be t2 and the t1 is pushed down. When the waterfall chart is filled with 256 data, the bottom of the y-axis should be t1 and the top of the y-axis should be t256. Is it possible to implement this?

Now I am using the uniform heatmap to implement it with yStart=0 and yStep=1. I tried to add the labelProvider to the y-axis to show the timestamp of each row. I am keeping an array locally to store the timestamp of each row which will be updated with the new data. I tried to map this array and return the timestamp in the y-axis labelProvider. But it doesn’t work. The y-axis will not be refreshed when data updated.

        yAxis.labelProvider.formatLabel = (dataValue) => {
        const ts = timestampArray[dataValue];
        if (ts) {
            const timeObj = new Date(ts);
            const hours = ('0' + timeObj.getHours()).slice(-2);
            const minutes = ('0' + timeObj.getMinutes()).slice(-2);
            const seconds = ('0' + timeObj.getSeconds()).slice(-2);
            const milliseconds = ('0' + timeObj.getMilliseconds()).slice(-3);
            return `${hours}:${minutes}:${seconds}.${milliseconds}`;
        } else {
            return "";
        }
    };
  • Quyen Sy asked 11 months ago
  • last active 10 months ago
1 vote
7k views

Hi,

I am getting console error and page is crashing and reloading the page.

0 votes
7k views

Hello Scichart team,

it’s possible to rotate yAxis (and put them horizontally), and adding some break lines if I have more than 1 word? Like:

https://prnt.sc/117pk6f

Waiting for feedback.

Many thanks,

Pedro Cruz

0 votes
7k views

Vertical Chart and pointMarker points are ploatted on somewhere on the canvas.

1 vote
7k views

Do scichart supports microsoft blazor ?
If yes, Any examples available ?

  • Abhilash R asked 3 years ago
  • last active 2 years ago
0 votes
7k views

pointMarker max and min values marker are cropped when autoRange is enabled. Check the attached image.

0 votes
0 answers
7k views

Hi, spotted a Typescript issue – the class declaration of SeriesInfo is missing at least two properties – zValue and formattedZValue. Noticed it because my IDE was complaining about their usage. Looking at a comparison of the class declaration and a console log of what actually exists, it looks like a few more might be missing too.

The above properties are also missing from the type docs.

Thanks!
Joe

0 votes
7k views

I am adding a LegendModifier to display legends for my chart as below:

_sciChartSurface.chartModifiers.add(new SciChart.LegendModifier({ showCheckboxes: true }));

My legend currently looks like the below, with very poor legend visibility:

![enter image description here][1]

I want to know how to set this legend to be opaque so that the labels may be seen clearly. What would be event better would be to just have a constant class for my legend collection (perhaps .sciChartLegendsContainer or whatever) so that I can apply my own css styling myself, without having to hack around with javascript.
Thanks

1 vote
7k views

Hi. I’m trying to add 3DChart to my vue project. And I have a question about the configuration. Can I download .data and .wasm files from the CDN.

For 2D charts , I’ve used recomendation of your release v.2.2:
SciChartSurface.useWasmFromCDN()
It works for me. How I can use CDN for SciChart3DSurface?

0 votes
7k views

I want to build a Stacked Column Side by Side Chart by referring to the reference here.

My code:

export class OutputAmplitudeComponent implements OnInit, OnDestroy {

yValues:any;
x:any;

constructor(@Inject(SETTING_SERVICE) private settingService: SettingService, private cdr: ChangeDetectorRef) {}

ngOnInit() {        
                this.settingService.registerSetting(OutputAmpSetting).pipe(takeUntil(this.ngUnsubAmplitudeData)).subscribe(setting => {
                    const OutputAmplitudeData = setting.value;

                    for (let x = 1; x < this.numberOfOutput; x++) {
                        if (this.OutputMode === 'Voltage') {
                            if (phaseNum === 1) {
                                this.ampSource.data[x-1].voltage1 = OutputAmplitudeData[x];
                            } else if (phaseNum === 2) {
                                this.ampSource.data[x-1].voltage2 = OutputAmplitudeData[x];
                            } else if (phaseNum === 3) {
                                this.ampSource.data[x-1].voltage3 = OutputAmplitudeData[x]; 
                            }
                        } else if (this.OutputMode === 'Current') {
                            if (phaseNum === 1) {
                                this.ampSource.data[x-1].current1 = OutputAmplitudeData[x];
                            } else if (phaseNum === 2) {
                                this.ampSource.data[x-1].current2 = OutputAmplitudeData[x];
                            } else if (phaseNum === 3) {
                                this.ampSource.data[x-1].current3 = OutputAmplitudeData[x];
                            }
                        }
        this.sciChartInit();
                    }   
                });
            }   

xValues = this.x;

phase1:number = parseFloat(this.ampSource.data[this.x-1].voltage1);
phase2:number = parseFloat(this.ampSource.data[this.x-1].voltage2);
phase3:number = parseFloat(this.ampSource.data[this.x-1].voltage3);

async sciChartInit() {

    const { wasmContext, sciChartSurface } = await SciChartSurface.create("chart");
    const xAxis = new NumericAxis(wasmContext);
    xAxis.labelProvider.numericFormat = ENumericFormat.Decimal_0;
    sciChartSurface.xAxes.add(xAxis);
    const yAxis = new NumericAxis(wasmContext);
    sciChartSurface.yAxes.add(yAxis);

    const dataSeries1 = new XyDataSeries(wasmContext, { xValues:this.x, yValues:this.phase1, dataSeriesName: "Phase 1" });
    const dataSeries2 = new XyDataSeries(wasmContext, { xValues:this.x, yValues:this.phase2, dataSeriesName: "Phase 2" });
    const dataSeries3 = new XyDataSeries(wasmContext, { xValues:this.x, yValues:this.phase3, dataSeriesName: "Phase 3" });

    const rendSeries1 = new StackedColumnRenderableSeries(wasmContext);
    rendSeries1.fill = "#dc443f";
    rendSeries1.stroke = "black";
    rendSeries1.strokeThickness = 1;
    rendSeries1.dataSeries = dataSeries1;
    rendSeries1.rolloverModifierProps.markerColor = "#b83735";
    rendSeries1.rolloverModifierProps.tooltipColor = "#dc443f";
    rendSeries1.rolloverModifierProps.tooltipTextColor = "#fff";
    rendSeries1.stackedGroupId = "one";

    const rendSeries2 = new StackedColumnRenderableSeries(wasmContext);
    rendSeries2.fill = "#aad34f";
    rendSeries2.stroke = "black";
    rendSeries2.strokeThickness = 1;
    rendSeries2.dataSeries = dataSeries2;
    rendSeries2.rolloverModifierProps.markerColor = "#87a73e";
    rendSeries2.rolloverModifierProps.tooltipColor = "#aad34f";
    rendSeries2.rolloverModifierProps.tooltipTextColor = "#000";
    rendSeries2.stackedGroupId = "two";

    const rendSeries3 = new StackedColumnRenderableSeries(wasmContext);
    rendSeries3.fill = "#8562b4";
    rendSeries3.stroke = "black";
    rendSeries3.strokeThickness = 1;
    rendSeries3.dataSeries = dataSeries3;
    rendSeries3.rolloverModifierProps.markerColor = "#715195";
    rendSeries3.rolloverModifierProps.tooltipColor = "#8562b4";
    rendSeries3.rolloverModifierProps.tooltipTextColor = "#fff";
    rendSeries3.stackedGroupId = "three";

    const verticallyStackedColumnCollection = new StackedColumnCollection(wasmContext);
    verticallyStackedColumnCollection.dataPointWidth = 0.5;
    verticallyStackedColumnCollection.add(rendSeries1, rendSeries2, rendSeries3);
    verticallyStackedColumnCollection.animation = new ScaleAnimation({ duration: 1000, fadeEffect: true });

    sciChartSurface.renderableSeries.add(verticallyStackedColumnCollection);

    sciChartSurface.chartModifiers.add(new ZoomExtentsModifier(), new ZoomPanModifier(), new MouseWheelZoomModifier());

    sciChartSurface.zoomExtents();

    sciChartSurface.chartModifiers.add(new RolloverModifier({ rolloverLineStroke: "#228B22" }));
    sciChartSurface.chartModifiers.add(
        new LegendModifier({
            placement: ELegendPlacement.TopRight,
            orientation: ELegendOrientation.Horizontal,
            showLegend: true,
            showCheckboxes: true,
            showSeriesMarkers: true
        })
    );
    return { wasmContext, sciChartSurface };
} }

.
Error:

ERROR in output-amplitude.component.ts: - error TS2322: Type 'number' is not assignable to type 'number[]'.
const dataSeries1 = new XyDataSeries(wasmContext, { xValues:this.x, yValues:this.phase1, dataSeriesName: "Phase 1" });                                                                     
node_modules/scichart/Charting/Model/XyDataSeries.d.ts:
yValues?: number[]; 
The expected type comes from property 'yValues' which is declared here on type 'IXyDataSeriesOptions'

.
.
I tried to parse the variables to numbers by using parseFloat in phase1 to phase3 but it did not solve error in yValues.
Any idea on the solution?

  • ETS Ong asked 3 years ago
  • last active 3 years ago
0 votes
7k views

I am getting a console error when using isVisible: false to the FastLineRenderableSeries or FastMountainRenderableSeries and CursorModifier together.

0 votes
7k views

I was looking over Tutorial 07 – Tooltips and Legends and the Chart Legends API demo, and noticed that the checkboxes and legend font had some styling applied. But, when I implement a legend on my own it uses the default font (or whatever global font style I used) and the default HTML checkbox styling. I was wondering if you had modified the styling using an outside CSS file, if there is an API endpoint for modifying the styling of the legend, or if this is possibly a bug. I did see that there was an applyTheme() method available, but I thought that it might not apply to this situation. I also tried to look through the example code provided for the Chart API Demo, but I couldn’t find anything that pointed one way or the other.

I have attached screenshots of what the legend looks like in the two examples, as well as a screenshot of what the legend looks like when I implement it on my own. I have also included a zip file with the demo application I created.

Thanks,
Drew

0 votes
6k views

On the vertical chart custom tooltipSvgTemplate seriesInfo isHit returns false always. Its working fine on the normal chart. Can you please check this issue is on verticle chart.

0 votes
6k views

Hi,
sciChartSurface.chartModifiers.clear() is getting error on the application. Its working on previous version and getting error on 1.4.1557.

0 votes
6k views

ZoomPanModifier date format charts zoom out continuously then showing NaN on the scale. It happened because the zoom level goes under the invalid date. Can you add the Minimum Zoom/Pan and Maximum Zoom/Pan area to be configured on options?

1 vote
6k views

I’m looking for some direction on how to implement a modifier that reacts to interaction (mouse up/down etc) with a charts axis

  • User clicks on axis
  • Provide callback for side effect when clicked

Thanks

0 votes
6k views

Hi, I’m looking for some pointers on how to implement the following:

  • User draws a selection on the chart (similar to rubber band modifier)
  • Annotation is drawn on the chart conforming to the users selection
  • Annotation is fixed relative to the data point (e.g. will scroll is the chart is panned etc)

Many thanks

1 vote
6k views

Hi, I wanted to make a multiple Y-Axis scale with multiple series plot into their respective Y scale. Like this,

Series A plot to 1st Y-axis Scale
Series B plot to 2nd Y-axis Scale
Series C plot to 3rd Y-axis Scale
Series D plot to 4th Y-axis Scale

and all those series are not overlapping each other. I want to do like the picture attached but with the series are not overlapping to each other.

0 votes
6k views

Hi

Is there any way to Create an image (as png) of an scichart surface and store it in Clipboard for later use in javascript?

0 votes
6k views

When I’m viewing a chart from mobile browser, quality of graphics is very low.
I can see pixels and some blurred graphics on mobile browsers. But it’s completely ok on the desktop browsers.

I reproduced it with an official example:
https://demo.scichart.com/javascript-realtime-ticking-stock-charts

  • Roman Zio asked 3 years ago
  • last active 1 year ago
1 vote
6k views

Hi Andrew:

It’s me again.

Does SciChart.js support Vue.js 2.0 or even 3.0 ?

Will there be any Vue templates in the future ?

Best Regards

Yen Wen

1 vote
6k views

I am having problem instantiating SciChart.js within a specific project and was hoping you might be able to help. To provide context I can run SciChart fine in simple projects and I suspect that I have a webpack issue.

When running a simple graph instantiation such as –

import React, { useEffect } from "react";
import ReactDOM from "react-dom";
import { SciChartSurface } from "scichart/Charting/Visuals/SciChartSurface";
import { NumericAxis } from "scichart/Charting/Visuals/Axis/NumericAxis";

export function MipsGraph(props) {
    useEffect(() => {       
        initSciChart();
    });

    return (
        <div id="depthGraph" style={{height: "100%"}} ></div>
    );
}

async function initSciChart() {
    const { sciChartSurface, wasmContext } = await SciChartSurface.create("depthGraph");

    const xAxis = new NumericAxis(wasmContext);
    const yAxis = new NumericAxis(wasmContext);

    sciChartSurface.xAxes.add(xAxis);
    sciChartSurface.yAxes.add(yAxis);
}

I see the following error

Uncaught (in promise) RuntimeError: abort(TypeError:
WebAssembly.instantiate(): Import #0 module=”env” error: module is not
an object or function). Build with -s ASSERTIONS=1 for more info.

and the warning –

wasm streaming compile failed: TypeError: WebAssembly.instantiate():
Import #0 module=”env” error: module is not an object or function

The warning is raised at line 7544 (after pretty print in chrome dev tools) of scichart2d.js?formatted at a line calling WebAssembly.instantiateStreaming(e,d). both e and d have values.

Debugging originally led me to believe that there was an issue finding the scichart2d.wasm file however network traffic clearly shows the file being fetched.

Any ideas?

1 vote
6k views

Hello

My application environment is on the mobile browser, so we need to switch between [pan] and [rollover]

When I use a button to switch, everything is fine, but when I want to switch with a long press, an exception occurs

Below is my code

    initModifier() {
        this.partitionList.forEach((obj, idx)=>{
            let sciChartSurface = this.sciObj[idx].sciChartSurface;
            this.zoomPanModifier[idx] = new ZoomPanModifier();
            this.rolloverModifier[idx] = new RolloverModifier({modifierGroup: this.modifierGroupId, showTooltip: false});
            this.zoomPanModifier[idx].isEnabled = true;
            // 擴增功能
            sciChartSurface.chartModifiers.add(
                this.zoomPanModifier[idx],
                new ZoomExtentsModifier(),
                new MouseWheelZoomModifier(),
                new PinchZoomModifier(),
            );
        });
    },
    switchCross() {
        let enablePan = !this.zoomPanModifier[0].isEnabled;
        this.partitionList.forEach((obj, idx)=>{
            let sciChartSurface = this.sciObj[idx].sciChartSurface;
            this.zoomPanModifier[idx].isEnabled = enablePan;
            if (enablePan)
                sciChartSurface.chartModifiers.removeAt(4);
            else
                sciChartSurface.chartModifiers.add(this.rolloverModifier[idx]);
        });
    },

I recorded a video, first use the button to switch, and then long press to switch, you can see the problem I want to narrate from the video, the URL is as follows: https://youtu.be/vJjbLNGS-iM

After the problem occurred, it was expected that touchmove should be [pan], but it became [zoom]

Thanks for your help

1 vote
6k views

We are having the first experiences with SCIchart. Could someone help with this problem we are experiencing?

[ encore ] ERROR Failed to compile with 1 errors14:42:33 [ encore ]
Module build failed: Module not found: [ encore ]
“./node_modules/scichart/_wasm/scichart2d.wasm” contains a reference
to the file “a”. This file can not be found, please check it for typos
or update it if the file got moved. [ encore ] ERROR in
./resources/js/Pages/Home.vue?vue&type=template&id=6a63e488&scoped=true&ts=true
(./node_modules/unplugin/dist/webpack/loaders/transform.js?unpluginName=unplugin-vue-components!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/Pages/Home.vue?vue&type=template&id=6a63e488&scoped=true&ts=true)
10:27 Module parse failed: Unexpected token (10:27) File was processed
with these loaders: *
./node_modules/unplugin/dist/webpack/loaders/transform.js *
./node_modules/unplugin/dist/webpack/loaders/transform.js *
./node_modules/vue-loader/dist/templateLoader.js *
./node_modules/vue-loader/dist/index.js You may need an additional
loader to handle the result of these loaders. | }, null, -1 /* HOISTED
*/)) |

export function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) { | return (_openBlock(),
_createElementBlock(“div”, _hoisted_1, [ | _createElementVNode(“h1”, null, _toDisplayString(_ctx.msg), 1 /* TEXT */),

ERROR in ./node_modules/scichart/_wasm/scichart2d.wasm Module not
found: Error: Can’t resolve ‘a’ in
‘C:\Users\clo\fr\Projeto\chart\App\node_modules\scichart_wasm’

ERROR in ./node_modules/scichart/_wasm/scichart3d.wasm Module not
found: Error: Can’t resolve ‘a’ in
‘C:\Users\clo\fr\Projeto\chart\App\node_modules\scichart_wasm’

webpack compiled with 3 errors

1 vote
6k views

I have a real-time updated chart with multiple series. Is it possible for me to add a custom annotation to the chart by just providing the x1 value? i.e. The y1 value will be the y value of the data point in certain series with the provided x1 value. It will look like that the annotation will be sticked to the series with a fixed x1 value while the chart is updating.

0 votes
6k views

Hello Scichart Team again,

I’m trying to replicate anything like this (check Screenshot_2.png).

I can update the scichart background, but I just wanted to have a single color in the background, but it seems that there is an overlap of colors in X / Y as I show in the next printscreen (check Screenshot_3.png)

How I can solve this?

Waiting for feedback.

Many thanks,

Pedro Cruz

0 votes
6k views

I wanted to use a stepline-box chart in my javascript applications for ELD, I failed to find out a similar box graph in the javascript chart section. The graph I have really looking for is attached here.
Could anyone please help me out?

1 vote
6k views
  1. SciChartSurface created with category x and numeric y axes
  2. ZoomPanModifier, ZoomExtentsModifier, MouseWheelZoomModifier, RolloverModifier added.
  3. Any series and dataSeries are initialized and added to the surface, but not filled with values yet.
  4. Value streaming started with delay.

The first error occurs when trying to zoom on empty surface :

Uncaught TypeError: Cannot read properties of undefined (reading 'width')
at MouseWheelZoomModifier2.ChartModifierBase2D2.growBy (ChartModifierBase2D.js:121:48)

And the other one when trying to drag:

Uncaught Error: category x axis with id=DefaultAxisId should have data series count > 0
at CategoryAxis2.CategoryAxisBase2.getCurrentCoordinateCalculatorInternal (CategoryAxisBase.js:95:19)

I have seen errors similar to the second one in other scenarios and sometimes it is fatal.
E.g i have tried to add annotation right after first value was added and first line raised similar error:

    const xCalc = this.surface.xAxes.get(0).getCurrentCoordinateCalculator() as CategoryCoordinateCalculator;
    const realX = xCalc.transformDataToIndex(time);
    const target = this.getOrAddAnnotation();
    target.x1 = realX;
    target.y1 = value;

Also getCurrentCoordinateCalculatorInternal error occurs when empty series & seriesData added without suspend.
I would appreciate any help and clarification

0 votes
6k views

I encountered an exception inside scichart2d.js when I used hitTestProvider.hitTest.

getHitTestInfo(idx, e) {
let touch0 = e.targetTouches[0];
let rect = e.currentTarget.getBoundingClientRect();
let x = parseInt(touch0.pageX - rect.left);
let y = parseInt(touch0.pageY - rect.top);
const premultipliedX = x * DpiHelper.PIXEL_RATIO;
const premultipliedY = y * DpiHelper.PIXEL_RATIO;
let lineSeries = this.$store.state.components.scitchart.sciObj[idx].sciChartSurface.renderableSeries.items[0];
console.log(`lineSeries.hitTestProvider.hitTest(${premultipliedX}, ${premultipliedY}, ${DpiHelper.PIXEL_RATIO})`);
let result = lineSeries.hitTestProvider.hitTest(premultipliedX, premultipliedY, DpiHelper.PIXEL_RATIO);
return result;

}

The video URL is as follows
https://youtu.be/3GIlv_ldorY

1 vote
6k views

How can I rotate the axis titles in SciChat JS?

We want the the titles Fp1 and Fp2 to be rotated so they are horizontal on the screen instead of vertical.

enter image description here

0 votes
6k views

I am getting a console error when using isVisible: false to the FastLineRenderableSeries or FastMountainRenderableSeries and CursorModifier together.

  const { wasmContext, sciChartSurface } = await SciChartSurface.create(
    "chart" + this.element
  );
  sciChartSurface.xAxes.add(
    new NumericAxis(wasmContext, { axisAlignment: EAxisAlignment.Top })
  );
  sciChartSurface.yAxes.add(
    new NumericAxis(wasmContext, {
      axisAlignment: EAxisAlignment.Left,
      growBy: new NumberRange(0.4, 0.4)
    })
  );

  const dataSeries = new XyDataSeries(wasmContext);
  const POINTS = 1000;
  const STEP = (3 * Math.PI) / POINTS;
  for (let i = 0; i <= 1000; i++) {
    const k = 1 - i / 2000;
    dataSeries.append(i, Math.sin(i * STEP) * k * 0.7);
  }

  const rendSeries = new FastLineRenderableSeries(wasmContext, {
    dataSeries: dataSeries,
    strokeThickness: 1,
    stroke: "red",
    isVisible: false
  });
  sciChartSurface.renderableSeries.add(rendSeries);
  // sciChartSurface.background = this.color;

  sciChartSurface.chartModifiers.add(
    new ZoomExtentsModifier(),
    new ZoomPanModifier(),
    new MouseWheelZoomModifier()
  );

  // Add CursorModifier behavior
  const cursorModifier = new CursorModifier({
    crosshairStroke: "#ff6600",
    crosshairStrokeThickness: 1,
    tooltipContainerBackground: "#000",
    tooltipTextStroke: "#ff6600",
    showTooltip: true,
    axisLabelsFill: "#b36200",
    axisLabelsStroke: "#fff"
  });
  sciChartSurface.chartModifiers.add(cursorModifier);

  sciChartSurface.zoomExtents();
  return { wasmContext, sciChartSurface };
1 vote
6k views

I have a bunch of series (XyScatterSeries) that I am using to draw different markers (triangle, circle, cross) based on the data. I also have couple line series too in the chart.

The line series should be displayed in the LegendModifier, but not any of the scatter series.

I tried setting “includeSeries” function here but that didn’t work (typescript kept complaining about it but I kept it and while running the app it didn’t hide the series):

return new LegendModifier({
        showCheckboxes: true,
        orientation: ELegendOrientation.Vertical,
        placement: ELegendPlacement.TopRight,
        includeSeries: (series: IRenderableSeries, isIncluded: boolean): void => { return false; },
    });

Then I created my own class “MyLegendModifier” deriving from LegendModifier, but that didn’t do anything either.

class MyLegendModifier extends LegendModifier {
    constructor(options?: ILegendModifierOptions) {
        super(options);
    }

    includeSeries(series: IRenderableSeries, isIncluded: boolean) {
        console.log('includeSeries:', series.id);
        if (series.id.startsWith('BUY:') || series.id.startsWith('SELL:')) {
            isIncluded = false;
        }
        super.includeSeries(series, isIncluded);
    }
}

Any advise please.

Showing 1 - 50 of 370 results

Try SciChart Today

Start a trial and discover why we are the choice
of demanding developers worldwide

Start TrialCase Studies