qesuite 1.0.36 → 1.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -618,7 +618,11 @@ declare const Distributions: {
618
618
  Critical(data: number[]): number;
619
619
  };
620
620
  ShapiroWilk: {
621
- Test(data: number[], expanded?: boolean): {
621
+ Royston(data: number[]): {
622
+ W: number;
623
+ p: number;
624
+ };
625
+ Test(data: number[], algorithmic?: boolean): {
622
626
  W: number;
623
627
  p: number;
624
628
  };
@@ -963,6 +967,7 @@ declare function CreateSummaryChart(charts: HTMLCanvasElement[], title: string):
963
967
  declare function CreateStackedChart(charts: Chart[], title?: string, chartSettings?: ChartSettings): HTMLCanvasElement;
964
968
  declare function GetFunctionValues(callback: Function, range: number[], count: number): DataSet;
965
969
  declare function QQPlotChart(data: number[], distribution?: string): HTMLCanvasElement;
970
+ declare function CreateControlChart(data: number[], chartTitle?: string, UCL?: number, LCL?: number): HTMLCanvasElement;
966
971
  /** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
967
972
  */
968
973
  /**
@@ -1145,4 +1150,4 @@ declare function GRRByPartChart(data: GRRData): HTMLCanvasElement;
1145
1150
  declare function GRRPartxOperatorChart(data: GRRData): HTMLCanvasElement;
1146
1151
  declare function CompileGRRObject(operators: any, parts: any, measurements: any): GRRData;
1147
1152
 
1148
- export { AnovaTableTwoWay, AverageMovingRange, AxisSettings, Beta, CanvasDrawSettings, Capability, Chart, ChartSettings, CompileGRRObject, CreateBoxandWhiskerGraph, CreateCapabilityHistogram, CreateCapabilityPlot, CreateCategoricalBarGraph, CreateContinuousBarGraph, CreateScatterPlot, CreateSplitGraph, CreateStackedChart, CreateSummaryChart, CustomGridline, DataCollection, DataSet, Distributions, ERF, EngFont, FixedPointIteration, G1, G1Graphs, GRR, GRRByPartChart, GRRData, GRRGraphs, GRROperator, GRRPartxOperatorChart, GRRReplication, GageEvaluation, Gamma, GetFunctionValues, GetHistogramDataset, GoodnessOfFit, IndividualDistributionIdentification, IndividualDistributionPlots, IndividualValuePlot, LastObservationsChart, Line, Margin, MaximumLikelihoodParameters, Mean, Median, MovingRange, MovingRangeChart, NewtonRaphson, ObjectToArray, ParameterizedCDF, Point, QQPlot, QQPlotChart, Rang, RoundTO, SerializeData, Specification, StDev, Sum, UnbiasingConstant, VarianceComponents };
1153
+ export { AnovaTableTwoWay, AverageMovingRange, AxisSettings, Beta, CanvasDrawSettings, Capability, Chart, ChartSettings, CompileGRRObject, CreateBoxandWhiskerGraph, CreateCapabilityHistogram, CreateCapabilityPlot, CreateCategoricalBarGraph, CreateContinuousBarGraph, CreateControlChart, CreateScatterPlot, CreateSplitGraph, CreateStackedChart, CreateSummaryChart, CustomGridline, DataCollection, DataSet, Distributions, ERF, EngFont, FixedPointIteration, G1, G1Graphs, GRR, GRRByPartChart, GRRData, GRRGraphs, GRROperator, GRRPartxOperatorChart, GRRReplication, GageEvaluation, Gamma, GetFunctionValues, GetHistogramDataset, GoodnessOfFit, IndividualDistributionIdentification, IndividualDistributionPlots, IndividualValuePlot, LastObservationsChart, Line, Margin, MaximumLikelihoodParameters, Mean, Median, MovingRange, MovingRangeChart, NewtonRaphson, ObjectToArray, ParameterizedCDF, Point, QQPlot, QQPlotChart, Rang, RoundTO, SerializeData, Specification, StDev, Sum, UnbiasingConstant, VarianceComponents };
package/dist/index.d.ts CHANGED
@@ -618,7 +618,11 @@ declare const Distributions: {
618
618
  Critical(data: number[]): number;
619
619
  };
620
620
  ShapiroWilk: {
621
- Test(data: number[], expanded?: boolean): {
621
+ Royston(data: number[]): {
622
+ W: number;
623
+ p: number;
624
+ };
625
+ Test(data: number[], algorithmic?: boolean): {
622
626
  W: number;
623
627
  p: number;
624
628
  };
@@ -963,6 +967,7 @@ declare function CreateSummaryChart(charts: HTMLCanvasElement[], title: string):
963
967
  declare function CreateStackedChart(charts: Chart[], title?: string, chartSettings?: ChartSettings): HTMLCanvasElement;
964
968
  declare function GetFunctionValues(callback: Function, range: number[], count: number): DataSet;
965
969
  declare function QQPlotChart(data: number[], distribution?: string): HTMLCanvasElement;
970
+ declare function CreateControlChart(data: number[], chartTitle?: string, UCL?: number, LCL?: number): HTMLCanvasElement;
966
971
  /** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
967
972
  */
968
973
  /**
@@ -1145,4 +1150,4 @@ declare function GRRByPartChart(data: GRRData): HTMLCanvasElement;
1145
1150
  declare function GRRPartxOperatorChart(data: GRRData): HTMLCanvasElement;
1146
1151
  declare function CompileGRRObject(operators: any, parts: any, measurements: any): GRRData;
1147
1152
 
1148
- export { AnovaTableTwoWay, AverageMovingRange, AxisSettings, Beta, CanvasDrawSettings, Capability, Chart, ChartSettings, CompileGRRObject, CreateBoxandWhiskerGraph, CreateCapabilityHistogram, CreateCapabilityPlot, CreateCategoricalBarGraph, CreateContinuousBarGraph, CreateScatterPlot, CreateSplitGraph, CreateStackedChart, CreateSummaryChart, CustomGridline, DataCollection, DataSet, Distributions, ERF, EngFont, FixedPointIteration, G1, G1Graphs, GRR, GRRByPartChart, GRRData, GRRGraphs, GRROperator, GRRPartxOperatorChart, GRRReplication, GageEvaluation, Gamma, GetFunctionValues, GetHistogramDataset, GoodnessOfFit, IndividualDistributionIdentification, IndividualDistributionPlots, IndividualValuePlot, LastObservationsChart, Line, Margin, MaximumLikelihoodParameters, Mean, Median, MovingRange, MovingRangeChart, NewtonRaphson, ObjectToArray, ParameterizedCDF, Point, QQPlot, QQPlotChart, Rang, RoundTO, SerializeData, Specification, StDev, Sum, UnbiasingConstant, VarianceComponents };
1153
+ export { AnovaTableTwoWay, AverageMovingRange, AxisSettings, Beta, CanvasDrawSettings, Capability, Chart, ChartSettings, CompileGRRObject, CreateBoxandWhiskerGraph, CreateCapabilityHistogram, CreateCapabilityPlot, CreateCategoricalBarGraph, CreateContinuousBarGraph, CreateControlChart, CreateScatterPlot, CreateSplitGraph, CreateStackedChart, CreateSummaryChart, CustomGridline, DataCollection, DataSet, Distributions, ERF, EngFont, FixedPointIteration, G1, G1Graphs, GRR, GRRByPartChart, GRRData, GRRGraphs, GRROperator, GRRPartxOperatorChart, GRRReplication, GageEvaluation, Gamma, GetFunctionValues, GetHistogramDataset, GoodnessOfFit, IndividualDistributionIdentification, IndividualDistributionPlots, IndividualValuePlot, LastObservationsChart, Line, Margin, MaximumLikelihoodParameters, Mean, Median, MovingRange, MovingRangeChart, NewtonRaphson, ObjectToArray, ParameterizedCDF, Point, QQPlot, QQPlotChart, Rang, RoundTO, SerializeData, Specification, StDev, Sum, UnbiasingConstant, VarianceComponents };
package/dist/index.js CHANGED
@@ -33,6 +33,7 @@ __export(QESuite_exports, {
33
33
  CreateCapabilityPlot: () => CreateCapabilityPlot,
34
34
  CreateCategoricalBarGraph: () => CreateCategoricalBarGraph,
35
35
  CreateContinuousBarGraph: () => CreateContinuousBarGraph,
36
+ CreateControlChart: () => CreateControlChart,
36
37
  CreateScatterPlot: () => CreateScatterPlot,
37
38
  CreateSplitGraph: () => CreateSplitGraph,
38
39
  CreateStackedChart: () => CreateStackedChart,
@@ -1670,7 +1671,37 @@ var Distributions = {
1670
1671
  }
1671
1672
  },
1672
1673
  ShapiroWilk: {
1673
- Test(data, expanded) {
1674
+ Royston(data) {
1675
+ let N = data.length;
1676
+ let mean = Mean(data);
1677
+ let sorted = [...data].sort();
1678
+ let u = 1 / Math.sqrt(N);
1679
+ let m_i = [];
1680
+ let M = 0;
1681
+ for (let i = 0; i < N; i++) {
1682
+ let m = Distributions.Normal.inv((i + 1 - 0.375) / (N + 0.25));
1683
+ m_i[i] = m;
1684
+ M += Math.pow(m, 2);
1685
+ }
1686
+ let a_i = [];
1687
+ a_i[N - 1] = -2.706056 * Math.pow(u, 5) + 4.434685 * Math.pow(u, 4) - 2.07119 * Math.pow(u, 3) - 0.147981 * Math.pow(u, 2) + 0.221157 * u + m_i[N - 1] / Math.sqrt(M);
1688
+ a_i[N - 2] = -3.582633 * Math.pow(u, 5) + 5.682633 * Math.pow(u, 4) - 1.752461 * Math.pow(u, 3) - 0.293762 * Math.pow(u, 2) + 0.042981 * u + m_i[N - 2] / Math.sqrt(M);
1689
+ a_i[0] = -1 * a_i[N - 1];
1690
+ a_i[1] = -1 * a_i[N - 2];
1691
+ let eps = (M - 2 * Math.pow(m_i[N - 1], 2) - 2 * Math.pow(m_i[N - 2], 2)) / (1 - 2 * Math.pow(a_i[N - 1], 2) - 2 * Math.pow(a_i[N - 2], 2));
1692
+ for (let i = 2; i < N - 2; i++) {
1693
+ a_i[i] = m_i[i] / Math.sqrt(eps);
1694
+ }
1695
+ let W = Math.pow(Correlate(a_i, sorted), 2);
1696
+ let p_mu = 38915e-7 * Math.pow(Math.log(N), 3) - 0.083751 * Math.pow(Math.log(N), 2) - 0.31082 * Math.log(N) - 1.5861;
1697
+ let p_sigma = Math.exp(30302e-7 * Math.pow(Math.log(N), 2) - 0.082676 * Math.log(N) - 0.4803);
1698
+ let z = (Math.log(1 - W) - p_mu) / p_sigma;
1699
+ return {
1700
+ W,
1701
+ p: 1 - Distributions.Normal.cdf(z, 0, 1)
1702
+ };
1703
+ },
1704
+ Test(data, algorithmic) {
1674
1705
  let N = data.length;
1675
1706
  let mean = Mean(data);
1676
1707
  let sorted = [...data].sort();
@@ -1679,39 +1710,21 @@ var Distributions = {
1679
1710
  sorted.forEach((s) => {
1680
1711
  SS += Math.pow(s - mean, 2);
1681
1712
  });
1682
- if (expanded || N > 50) {
1683
- let u = 1 / Math.sqrt(N);
1684
- let m_i = [];
1685
- let M = 0;
1686
- for (let i = 0; i < N; i++) {
1687
- let m = Distributions.Normal.inv((i + 1 - 0.375) / (N + 0.25));
1688
- m_i[i] = m;
1689
- M += Math.pow(m, 2);
1690
- }
1691
- let a_i = [];
1692
- a_i[N - 1] = -2.706056 * Math.pow(u, 5) + 4.434685 * Math.pow(u, 4) - 2.07119 * Math.pow(u, 3) - 0.147981 * Math.pow(u, 2) + 0.221157 * u + m_i[N - 1] / Math.sqrt(M);
1693
- a_i[N - 2] = -3.582633 * Math.pow(u, 5) + 5.682633 * Math.pow(u, 4) - 1.752461 * Math.pow(u, 3) - 0.293762 * Math.pow(u, 2) + 0.042981 * u + m_i[N - 2] / Math.sqrt(M);
1694
- a_i[0] = -1 * a_i[N - 1];
1695
- a_i[1] = -1 * a_i[N - 2];
1696
- let eps = (M - 2 * Math.pow(m_i[N - 1], 2) - 2 * Math.pow(m_i[N - 2], 2)) / (1 - 2 * Math.pow(a_i[N - 1], 2) - 2 * Math.pow(a_i[N - 2], 2));
1697
- for (let i = 2; i < N - 2; i++) {
1698
- a_i[i] = m_i[i] / Math.sqrt(eps);
1699
- }
1700
- let W2 = Math.pow(Correlate(a_i, sorted), 2);
1701
- let p_mu = 38915e-7 * Math.pow(Math.log(N), 3) - 0.083751 * Math.pow(Math.log(N), 2) - 0.31082 * Math.log(N) - 1.5861;
1702
- let p_sigma = Math.exp(30302e-7 * Math.pow(Math.log(N), 2) - 0.082676 * Math.log(N) - 0.4803);
1703
- let z = (Math.log(1 - W2) - p_mu) / p_sigma;
1704
- return {
1705
- W: W2,
1706
- p: 1 - Distributions.Normal.cdf(z, 0, 1)
1707
- };
1708
- }
1709
1713
  let b = 0;
1710
1714
  for (let i = 0; i < Math.floor(N / 2); i++) {
1711
1715
  let a = Distributions.Normal.ShapiroWilk.constants[i][N - 2];
1712
1716
  b += a * (invSort[i] - sorted[i]);
1713
1717
  }
1714
1718
  let W = Math.pow(b, 2) / SS;
1719
+ if (algorithmic) {
1720
+ let p_mu = 38915e-7 * Math.pow(Math.log(N), 3) - 0.083751 * Math.pow(Math.log(N), 2) - 0.31082 * Math.log(N) - 1.5861;
1721
+ let p_sigma = Math.exp(30302e-7 * Math.pow(Math.log(N), 2) - 0.082676 * Math.log(N) - 0.4803);
1722
+ let z = (Math.log(1 - W) - p_mu) / p_sigma;
1723
+ return {
1724
+ W,
1725
+ p: 1 - Distributions.Normal.cdf(z, 0, 1)
1726
+ };
1727
+ }
1715
1728
  let p = Distributions.Normal.ShapiroWilk.p(W, N);
1716
1729
  return {
1717
1730
  W,
@@ -3179,7 +3192,7 @@ function CreateScatterPlot(data, title, chartSettings) {
3179
3192
  AddPlotBorder(ctx, chartSettings);
3180
3193
  return canvas;
3181
3194
  }
3182
- function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSettings("red", "black", 1, 1), controlTests = [1, 2, 3, 4, 5, 6, 7, 8]) {
3195
+ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSettings("red", "red", 1, 1), controlTests = [1]) {
3183
3196
  if (CL === void 0) {
3184
3197
  CL = Mean([LCL, UCL]);
3185
3198
  }
@@ -3200,7 +3213,7 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3200
3213
  if (controlTests.includes(2) && (v.y > CL && Test2 >= 0 || v.y < CL && Test2 <= 0)) {
3201
3214
  Test2 += v.y < CL ? -1 : 1;
3202
3215
  if (Test2 >= 8 || Test2 <= -8) {
3203
- v.display = display;
3216
+ v.display = new CanvasDrawSettings("orange", "red", 1, 1);
3204
3217
  }
3205
3218
  } else {
3206
3219
  Test2 = 0;
@@ -3209,7 +3222,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3209
3222
  if (controlTests.includes(3) && (v.y > data.values[i - 1].y && Test3 >= 0 || v.y < data.values[i - 1].y && Test3 <= 0)) {
3210
3223
  Test3 += v.y < data.values[i - 1].y ? -1 : 1;
3211
3224
  if (Test3 >= 5 || Test3 <= -6) {
3212
- v.display = display;
3225
+ v.display = new CanvasDrawSettings("yellow", "red", 1, 1);
3226
+ ;
3213
3227
  }
3214
3228
  } else {
3215
3229
  Test3 = 0;
@@ -3221,7 +3235,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3221
3235
  Test4 = 0;
3222
3236
  }
3223
3237
  if (Math.abs(Test4) >= 13) {
3224
- v.display = display;
3238
+ v.display = new CanvasDrawSettings("purple", "red", 1, 1);
3239
+ ;
3225
3240
  }
3226
3241
  }
3227
3242
  if (controlTests.includes(4) && v.y > data.values[i - 1].y) {
@@ -3231,7 +3246,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3231
3246
  Test4 = 0;
3232
3247
  }
3233
3248
  if (Math.abs(Test4) >= 13) {
3234
- v.display = display;
3249
+ v.display = new CanvasDrawSettings("purple", "red", 1, 1);
3250
+ ;
3235
3251
  }
3236
3252
  }
3237
3253
  }
@@ -3240,7 +3256,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3240
3256
  if (controlTests.includes(5) && v.y > 2 * std + CL) {
3241
3257
  Test5[2] = 1;
3242
3258
  if (Test5[0] === 1 || Test5[1] === 1) {
3243
- v.display = display;
3259
+ v.display = new CanvasDrawSettings("white", "red", 1, 1);
3260
+ ;
3244
3261
  }
3245
3262
  }
3246
3263
  if (controlTests.includes(5) && v.y < CL - 2 * std) {
@@ -3258,7 +3275,7 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3258
3275
  Test6[5] = 1;
3259
3276
  let plus = Test6.filter((t) => t === 1);
3260
3277
  if (plus.length >= 4) {
3261
- v.display = display;
3278
+ v.display = new CanvasDrawSettings("grey", "red", 1, 1);
3262
3279
  }
3263
3280
  } else if (controlTests.includes(6) && v.y < CL - std) {
3264
3281
  Test6[5] = -1;
@@ -3272,7 +3289,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3272
3289
  if (controlTests.includes(7) && v.y >= CL - std && v.y <= CL + std) {
3273
3290
  Test7 += 1;
3274
3291
  if (Test7 >= 15) {
3275
- v.display = display;
3292
+ v.display = new CanvasDrawSettings("pink", "red", 1, 1);
3293
+ ;
3276
3294
  }
3277
3295
  } else {
3278
3296
  Test7 = 0;
@@ -3280,7 +3298,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3280
3298
  if (controlTests.includes(8) && (v.y < CL - std || v.y > CL + std)) {
3281
3299
  Test8 += 1;
3282
3300
  if (Test8 >= 8) {
3283
- v.display = display;
3301
+ v.display = new CanvasDrawSettings("brown", "red", 1, 1);
3302
+ ;
3284
3303
  }
3285
3304
  } else {
3286
3305
  Test8 = 0;
@@ -3634,12 +3653,33 @@ function QQPlotChart(data, distribution = "Normal") {
3634
3653
  let chart = CreateStackedChart([middleLineChart, new Chart([dataset], "scatter")], `${distribution[0].toUpperCase()}${distribution.substring(1)} Probability Plot`, chartSettings);
3635
3654
  if (distribution.toLowerCase() === "normal" || distribution.toLowerCase().includes("boxcox")) {
3636
3655
  let AD = GoodnessOfFit.AndersonDarling.Test(data, GoodnessOfFit.Distributions.Normal);
3637
- let RJ = Distributions.Normal.RyanJoiner.Test(data);
3638
- let KS = Distributions.Normal.KolmogorovSmirnov(data);
3639
3656
  let JB = Distributions.Normal.JarqueBera(data);
3657
+ let KS = Distributions.Normal.KolmogorovSmirnov(data);
3658
+ let LF = Distributions.Normal.Lilliefors.Test(data);
3659
+ let RJ = Distributions.Normal.RyanJoiner.Test(data);
3660
+ let SWR = Distributions.Normal.ShapiroWilk.Royston(data);
3640
3661
  let ctx = chart.getContext("2d");
3641
3662
  if (ctx) {
3642
- AddInfoTable(ctx, [{ key: "AD:", value: AD.AD }, { key: "p-value:", value: AD.p }, { key: "", value: "" }, { key: "RJ:", value: RJ.RJ }, { key: "crit.:", value: RJ.critical }, { key: "", value: "" }, { key: "KS:", value: KS.KS }, { key: "p-value:", value: KS.p }, { key: "", value: "" }, { key: "JB:", value: JB.JB }, { key: "p-value:", value: JB.p }], 1075, 150, 175, 100, "", 30);
3663
+ AddInfoTable(ctx, [
3664
+ { key: "AD:", value: AD.AD },
3665
+ { key: "p-value:", value: AD.p },
3666
+ { key: "", value: "" },
3667
+ { key: "JB:", value: JB.JB },
3668
+ { key: "p-value:", value: JB.p },
3669
+ { key: "", value: "" },
3670
+ { key: "KS:", value: KS.KS },
3671
+ { key: "p-value:", value: KS.p },
3672
+ { key: "", value: "" },
3673
+ { key: "Lf:", value: LF.KS },
3674
+ { key: "p-value:", value: LF.p },
3675
+ { key: "", value: "" },
3676
+ { key: "RJ:", value: RJ.RJ },
3677
+ { key: "crit.:", value: RJ.critical },
3678
+ { key: "", value: "" },
3679
+ { key: "SW(R):", value: SWR.W },
3680
+ { key: "p-value:", value: SWR.p },
3681
+ { key: "", value: "" }
3682
+ ], 1075, 150, 175, 100, "", 30);
3643
3683
  }
3644
3684
  } else {
3645
3685
  let dist = distribution.replace("-", "").replace("arameter", "").replace(/\s/g, "");
@@ -3685,6 +3725,30 @@ function QQDistributionModificationX(p, distribution, data) {
3685
3725
  }
3686
3726
  return p;
3687
3727
  }
3728
+ function CreateControlChart(data, chartTitle, UCL, LCL) {
3729
+ let centerline = Mean(data);
3730
+ let std = StDev.S(data);
3731
+ if (UCL === void 0) {
3732
+ UCL = centerline + 3 * std;
3733
+ }
3734
+ if (LCL === void 0) {
3735
+ LCL = centerline - 3 * std;
3736
+ }
3737
+ let dataSet = new DataSet(data.map((d, i) => {
3738
+ return new Point(i, d);
3739
+ }));
3740
+ dataSet.line.type = "straight";
3741
+ let customGridlines = [
3742
+ new CustomGridline(centerline, `x\u0304 = ${Math.round(centerline * 1e3) / 1e3}`, new CanvasDrawSettings("", "green"), void 0, true),
3743
+ new CustomGridline(LCL, `LCL = ${Math.round(LCL * 1e3) / 1e3}`, new CanvasDrawSettings("", "maroon"), void 0, true),
3744
+ new CustomGridline(UCL, `UCL = ${Math.round(UCL * 1e3) / 1e3}`, new CanvasDrawSettings("", "maroon"), void 0, true)
3745
+ ];
3746
+ let chartSettings = new ChartSettings();
3747
+ chartSettings.axis.y.customGridlines = customGridlines;
3748
+ MarkOutOfControl(dataSet, UCL, LCL, centerline, std);
3749
+ let graph = CreateScatterPlot([dataSet], chartTitle, chartSettings);
3750
+ return graph;
3751
+ }
3688
3752
  function AnovaTableTwoWay(data, interaction) {
3689
3753
  let ANOVA;
3690
3754
  if (!interaction) {
@@ -4364,6 +4428,7 @@ function SplitObjectArrayByProp(array, prop) {
4364
4428
  CreateCapabilityPlot,
4365
4429
  CreateCategoricalBarGraph,
4366
4430
  CreateContinuousBarGraph,
4431
+ CreateControlChart,
4367
4432
  CreateScatterPlot,
4368
4433
  CreateSplitGraph,
4369
4434
  CreateStackedChart,
package/dist/index.mjs CHANGED
@@ -1584,7 +1584,37 @@ var Distributions = {
1584
1584
  }
1585
1585
  },
1586
1586
  ShapiroWilk: {
1587
- Test(data, expanded) {
1587
+ Royston(data) {
1588
+ let N = data.length;
1589
+ let mean = Mean(data);
1590
+ let sorted = [...data].sort();
1591
+ let u = 1 / Math.sqrt(N);
1592
+ let m_i = [];
1593
+ let M = 0;
1594
+ for (let i = 0; i < N; i++) {
1595
+ let m = Distributions.Normal.inv((i + 1 - 0.375) / (N + 0.25));
1596
+ m_i[i] = m;
1597
+ M += Math.pow(m, 2);
1598
+ }
1599
+ let a_i = [];
1600
+ a_i[N - 1] = -2.706056 * Math.pow(u, 5) + 4.434685 * Math.pow(u, 4) - 2.07119 * Math.pow(u, 3) - 0.147981 * Math.pow(u, 2) + 0.221157 * u + m_i[N - 1] / Math.sqrt(M);
1601
+ a_i[N - 2] = -3.582633 * Math.pow(u, 5) + 5.682633 * Math.pow(u, 4) - 1.752461 * Math.pow(u, 3) - 0.293762 * Math.pow(u, 2) + 0.042981 * u + m_i[N - 2] / Math.sqrt(M);
1602
+ a_i[0] = -1 * a_i[N - 1];
1603
+ a_i[1] = -1 * a_i[N - 2];
1604
+ let eps = (M - 2 * Math.pow(m_i[N - 1], 2) - 2 * Math.pow(m_i[N - 2], 2)) / (1 - 2 * Math.pow(a_i[N - 1], 2) - 2 * Math.pow(a_i[N - 2], 2));
1605
+ for (let i = 2; i < N - 2; i++) {
1606
+ a_i[i] = m_i[i] / Math.sqrt(eps);
1607
+ }
1608
+ let W = Math.pow(Correlate(a_i, sorted), 2);
1609
+ let p_mu = 38915e-7 * Math.pow(Math.log(N), 3) - 0.083751 * Math.pow(Math.log(N), 2) - 0.31082 * Math.log(N) - 1.5861;
1610
+ let p_sigma = Math.exp(30302e-7 * Math.pow(Math.log(N), 2) - 0.082676 * Math.log(N) - 0.4803);
1611
+ let z = (Math.log(1 - W) - p_mu) / p_sigma;
1612
+ return {
1613
+ W,
1614
+ p: 1 - Distributions.Normal.cdf(z, 0, 1)
1615
+ };
1616
+ },
1617
+ Test(data, algorithmic) {
1588
1618
  let N = data.length;
1589
1619
  let mean = Mean(data);
1590
1620
  let sorted = [...data].sort();
@@ -1593,39 +1623,21 @@ var Distributions = {
1593
1623
  sorted.forEach((s) => {
1594
1624
  SS += Math.pow(s - mean, 2);
1595
1625
  });
1596
- if (expanded || N > 50) {
1597
- let u = 1 / Math.sqrt(N);
1598
- let m_i = [];
1599
- let M = 0;
1600
- for (let i = 0; i < N; i++) {
1601
- let m = Distributions.Normal.inv((i + 1 - 0.375) / (N + 0.25));
1602
- m_i[i] = m;
1603
- M += Math.pow(m, 2);
1604
- }
1605
- let a_i = [];
1606
- a_i[N - 1] = -2.706056 * Math.pow(u, 5) + 4.434685 * Math.pow(u, 4) - 2.07119 * Math.pow(u, 3) - 0.147981 * Math.pow(u, 2) + 0.221157 * u + m_i[N - 1] / Math.sqrt(M);
1607
- a_i[N - 2] = -3.582633 * Math.pow(u, 5) + 5.682633 * Math.pow(u, 4) - 1.752461 * Math.pow(u, 3) - 0.293762 * Math.pow(u, 2) + 0.042981 * u + m_i[N - 2] / Math.sqrt(M);
1608
- a_i[0] = -1 * a_i[N - 1];
1609
- a_i[1] = -1 * a_i[N - 2];
1610
- let eps = (M - 2 * Math.pow(m_i[N - 1], 2) - 2 * Math.pow(m_i[N - 2], 2)) / (1 - 2 * Math.pow(a_i[N - 1], 2) - 2 * Math.pow(a_i[N - 2], 2));
1611
- for (let i = 2; i < N - 2; i++) {
1612
- a_i[i] = m_i[i] / Math.sqrt(eps);
1613
- }
1614
- let W2 = Math.pow(Correlate(a_i, sorted), 2);
1615
- let p_mu = 38915e-7 * Math.pow(Math.log(N), 3) - 0.083751 * Math.pow(Math.log(N), 2) - 0.31082 * Math.log(N) - 1.5861;
1616
- let p_sigma = Math.exp(30302e-7 * Math.pow(Math.log(N), 2) - 0.082676 * Math.log(N) - 0.4803);
1617
- let z = (Math.log(1 - W2) - p_mu) / p_sigma;
1618
- return {
1619
- W: W2,
1620
- p: 1 - Distributions.Normal.cdf(z, 0, 1)
1621
- };
1622
- }
1623
1626
  let b = 0;
1624
1627
  for (let i = 0; i < Math.floor(N / 2); i++) {
1625
1628
  let a = Distributions.Normal.ShapiroWilk.constants[i][N - 2];
1626
1629
  b += a * (invSort[i] - sorted[i]);
1627
1630
  }
1628
1631
  let W = Math.pow(b, 2) / SS;
1632
+ if (algorithmic) {
1633
+ let p_mu = 38915e-7 * Math.pow(Math.log(N), 3) - 0.083751 * Math.pow(Math.log(N), 2) - 0.31082 * Math.log(N) - 1.5861;
1634
+ let p_sigma = Math.exp(30302e-7 * Math.pow(Math.log(N), 2) - 0.082676 * Math.log(N) - 0.4803);
1635
+ let z = (Math.log(1 - W) - p_mu) / p_sigma;
1636
+ return {
1637
+ W,
1638
+ p: 1 - Distributions.Normal.cdf(z, 0, 1)
1639
+ };
1640
+ }
1629
1641
  let p = Distributions.Normal.ShapiroWilk.p(W, N);
1630
1642
  return {
1631
1643
  W,
@@ -3093,7 +3105,7 @@ function CreateScatterPlot(data, title, chartSettings) {
3093
3105
  AddPlotBorder(ctx, chartSettings);
3094
3106
  return canvas;
3095
3107
  }
3096
- function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSettings("red", "black", 1, 1), controlTests = [1, 2, 3, 4, 5, 6, 7, 8]) {
3108
+ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSettings("red", "red", 1, 1), controlTests = [1]) {
3097
3109
  if (CL === void 0) {
3098
3110
  CL = Mean([LCL, UCL]);
3099
3111
  }
@@ -3114,7 +3126,7 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3114
3126
  if (controlTests.includes(2) && (v.y > CL && Test2 >= 0 || v.y < CL && Test2 <= 0)) {
3115
3127
  Test2 += v.y < CL ? -1 : 1;
3116
3128
  if (Test2 >= 8 || Test2 <= -8) {
3117
- v.display = display;
3129
+ v.display = new CanvasDrawSettings("orange", "red", 1, 1);
3118
3130
  }
3119
3131
  } else {
3120
3132
  Test2 = 0;
@@ -3123,7 +3135,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3123
3135
  if (controlTests.includes(3) && (v.y > data.values[i - 1].y && Test3 >= 0 || v.y < data.values[i - 1].y && Test3 <= 0)) {
3124
3136
  Test3 += v.y < data.values[i - 1].y ? -1 : 1;
3125
3137
  if (Test3 >= 5 || Test3 <= -6) {
3126
- v.display = display;
3138
+ v.display = new CanvasDrawSettings("yellow", "red", 1, 1);
3139
+ ;
3127
3140
  }
3128
3141
  } else {
3129
3142
  Test3 = 0;
@@ -3135,7 +3148,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3135
3148
  Test4 = 0;
3136
3149
  }
3137
3150
  if (Math.abs(Test4) >= 13) {
3138
- v.display = display;
3151
+ v.display = new CanvasDrawSettings("purple", "red", 1, 1);
3152
+ ;
3139
3153
  }
3140
3154
  }
3141
3155
  if (controlTests.includes(4) && v.y > data.values[i - 1].y) {
@@ -3145,7 +3159,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3145
3159
  Test4 = 0;
3146
3160
  }
3147
3161
  if (Math.abs(Test4) >= 13) {
3148
- v.display = display;
3162
+ v.display = new CanvasDrawSettings("purple", "red", 1, 1);
3163
+ ;
3149
3164
  }
3150
3165
  }
3151
3166
  }
@@ -3154,7 +3169,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3154
3169
  if (controlTests.includes(5) && v.y > 2 * std + CL) {
3155
3170
  Test5[2] = 1;
3156
3171
  if (Test5[0] === 1 || Test5[1] === 1) {
3157
- v.display = display;
3172
+ v.display = new CanvasDrawSettings("white", "red", 1, 1);
3173
+ ;
3158
3174
  }
3159
3175
  }
3160
3176
  if (controlTests.includes(5) && v.y < CL - 2 * std) {
@@ -3172,7 +3188,7 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3172
3188
  Test6[5] = 1;
3173
3189
  let plus = Test6.filter((t) => t === 1);
3174
3190
  if (plus.length >= 4) {
3175
- v.display = display;
3191
+ v.display = new CanvasDrawSettings("grey", "red", 1, 1);
3176
3192
  }
3177
3193
  } else if (controlTests.includes(6) && v.y < CL - std) {
3178
3194
  Test6[5] = -1;
@@ -3186,7 +3202,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3186
3202
  if (controlTests.includes(7) && v.y >= CL - std && v.y <= CL + std) {
3187
3203
  Test7 += 1;
3188
3204
  if (Test7 >= 15) {
3189
- v.display = display;
3205
+ v.display = new CanvasDrawSettings("pink", "red", 1, 1);
3206
+ ;
3190
3207
  }
3191
3208
  } else {
3192
3209
  Test7 = 0;
@@ -3194,7 +3211,8 @@ function MarkOutOfControl(data, UCL, LCL, CL, std, display = new CanvasDrawSetti
3194
3211
  if (controlTests.includes(8) && (v.y < CL - std || v.y > CL + std)) {
3195
3212
  Test8 += 1;
3196
3213
  if (Test8 >= 8) {
3197
- v.display = display;
3214
+ v.display = new CanvasDrawSettings("brown", "red", 1, 1);
3215
+ ;
3198
3216
  }
3199
3217
  } else {
3200
3218
  Test8 = 0;
@@ -3548,12 +3566,33 @@ function QQPlotChart(data, distribution = "Normal") {
3548
3566
  let chart = CreateStackedChart([middleLineChart, new Chart([dataset], "scatter")], `${distribution[0].toUpperCase()}${distribution.substring(1)} Probability Plot`, chartSettings);
3549
3567
  if (distribution.toLowerCase() === "normal" || distribution.toLowerCase().includes("boxcox")) {
3550
3568
  let AD = GoodnessOfFit.AndersonDarling.Test(data, GoodnessOfFit.Distributions.Normal);
3551
- let RJ = Distributions.Normal.RyanJoiner.Test(data);
3552
- let KS = Distributions.Normal.KolmogorovSmirnov(data);
3553
3569
  let JB = Distributions.Normal.JarqueBera(data);
3570
+ let KS = Distributions.Normal.KolmogorovSmirnov(data);
3571
+ let LF = Distributions.Normal.Lilliefors.Test(data);
3572
+ let RJ = Distributions.Normal.RyanJoiner.Test(data);
3573
+ let SWR = Distributions.Normal.ShapiroWilk.Royston(data);
3554
3574
  let ctx = chart.getContext("2d");
3555
3575
  if (ctx) {
3556
- AddInfoTable(ctx, [{ key: "AD:", value: AD.AD }, { key: "p-value:", value: AD.p }, { key: "", value: "" }, { key: "RJ:", value: RJ.RJ }, { key: "crit.:", value: RJ.critical }, { key: "", value: "" }, { key: "KS:", value: KS.KS }, { key: "p-value:", value: KS.p }, { key: "", value: "" }, { key: "JB:", value: JB.JB }, { key: "p-value:", value: JB.p }], 1075, 150, 175, 100, "", 30);
3576
+ AddInfoTable(ctx, [
3577
+ { key: "AD:", value: AD.AD },
3578
+ { key: "p-value:", value: AD.p },
3579
+ { key: "", value: "" },
3580
+ { key: "JB:", value: JB.JB },
3581
+ { key: "p-value:", value: JB.p },
3582
+ { key: "", value: "" },
3583
+ { key: "KS:", value: KS.KS },
3584
+ { key: "p-value:", value: KS.p },
3585
+ { key: "", value: "" },
3586
+ { key: "Lf:", value: LF.KS },
3587
+ { key: "p-value:", value: LF.p },
3588
+ { key: "", value: "" },
3589
+ { key: "RJ:", value: RJ.RJ },
3590
+ { key: "crit.:", value: RJ.critical },
3591
+ { key: "", value: "" },
3592
+ { key: "SW(R):", value: SWR.W },
3593
+ { key: "p-value:", value: SWR.p },
3594
+ { key: "", value: "" }
3595
+ ], 1075, 150, 175, 100, "", 30);
3557
3596
  }
3558
3597
  } else {
3559
3598
  let dist = distribution.replace("-", "").replace("arameter", "").replace(/\s/g, "");
@@ -3599,6 +3638,30 @@ function QQDistributionModificationX(p, distribution, data) {
3599
3638
  }
3600
3639
  return p;
3601
3640
  }
3641
+ function CreateControlChart(data, chartTitle, UCL, LCL) {
3642
+ let centerline = Mean(data);
3643
+ let std = StDev.S(data);
3644
+ if (UCL === void 0) {
3645
+ UCL = centerline + 3 * std;
3646
+ }
3647
+ if (LCL === void 0) {
3648
+ LCL = centerline - 3 * std;
3649
+ }
3650
+ let dataSet = new DataSet(data.map((d, i) => {
3651
+ return new Point(i, d);
3652
+ }));
3653
+ dataSet.line.type = "straight";
3654
+ let customGridlines = [
3655
+ new CustomGridline(centerline, `x\u0304 = ${Math.round(centerline * 1e3) / 1e3}`, new CanvasDrawSettings("", "green"), void 0, true),
3656
+ new CustomGridline(LCL, `LCL = ${Math.round(LCL * 1e3) / 1e3}`, new CanvasDrawSettings("", "maroon"), void 0, true),
3657
+ new CustomGridline(UCL, `UCL = ${Math.round(UCL * 1e3) / 1e3}`, new CanvasDrawSettings("", "maroon"), void 0, true)
3658
+ ];
3659
+ let chartSettings = new ChartSettings();
3660
+ chartSettings.axis.y.customGridlines = customGridlines;
3661
+ MarkOutOfControl(dataSet, UCL, LCL, centerline, std);
3662
+ let graph = CreateScatterPlot([dataSet], chartTitle, chartSettings);
3663
+ return graph;
3664
+ }
3602
3665
  function AnovaTableTwoWay(data, interaction) {
3603
3666
  let ANOVA;
3604
3667
  if (!interaction) {
@@ -4277,6 +4340,7 @@ export {
4277
4340
  CreateCapabilityPlot,
4278
4341
  CreateCategoricalBarGraph,
4279
4342
  CreateContinuousBarGraph,
4343
+ CreateControlChart,
4280
4344
  CreateScatterPlot,
4281
4345
  CreateSplitGraph,
4282
4346
  CreateStackedChart,
package/index.ts CHANGED
@@ -1748,7 +1748,44 @@ export const Distributions = {
1748
1748
  }
1749
1749
  },
1750
1750
  ShapiroWilk:{
1751
- Test(data: number[], expanded?: boolean){
1751
+ Royston(data: number[]){
1752
+ let N = data.length;
1753
+ let mean = Mean(data);
1754
+
1755
+ let sorted = [...data].sort();
1756
+
1757
+ let u = 1/Math.sqrt(N);
1758
+ let m_i: number[] = [];
1759
+ let M = 0;
1760
+ for(let i = 0; i < N; i++){
1761
+ let m = Distributions.Normal.inv((i+1-0.375)/(N+.25));
1762
+ m_i[i] = m;
1763
+ M += Math.pow(m,2);
1764
+ }
1765
+
1766
+ let a_i: number[] = [];
1767
+ a_i[N - 1] = -2.706056*Math.pow(u,5)+4.434685*Math.pow(u,4)-2.07119*Math.pow(u,3)-0.147981*Math.pow(u,2)+0.221157*u+m_i[N - 1]/Math.sqrt(M);
1768
+ a_i[N - 2] = -3.582633*Math.pow(u,5)+5.682633*Math.pow(u,4)-1.752461*Math.pow(u,3)-0.293762*Math.pow(u,2)+0.042981*u+m_i[N - 2]/Math.sqrt(M);
1769
+ a_i[0] = -1 * a_i[N-1];
1770
+ a_i[1] = -1 * a_i[N-2];
1771
+ let eps = (M-2*Math.pow(m_i[N-1],2)-2*Math.pow(m_i[N-2],2))/(1-2*Math.pow(a_i[N-1],2)-2*Math.pow(a_i[N-2],2))
1772
+
1773
+ for(let i = 2; i < N-2; i++){
1774
+ a_i[i] = m_i[i]/Math.sqrt(eps);
1775
+ }
1776
+
1777
+ let W = Math.pow(Correlate(a_i, sorted), 2);
1778
+
1779
+ let p_mu = 0.0038915*Math.pow(Math.log(N),3)-0.083751*Math.pow(Math.log(N),2)-0.31082*Math.log(N)-1.5861;
1780
+ let p_sigma = Math.exp(0.0030302*Math.pow(Math.log(N),2)-0.082676*Math.log(N)-0.4803);
1781
+ let z = (Math.log(1 - W) - p_mu)/p_sigma;
1782
+
1783
+ return {
1784
+ W: W,
1785
+ p: 1 - Distributions.Normal.cdf(z, 0, 1)
1786
+ }
1787
+ },
1788
+ Test(data: number[], algorithmic?: boolean){
1752
1789
  let N = data.length;
1753
1790
  let mean = Mean(data);
1754
1791
 
@@ -1759,46 +1796,25 @@ export const Distributions = {
1759
1796
  sorted.forEach(s => {
1760
1797
  SS += Math.pow(s - mean, 2);
1761
1798
  })
1762
- // ShapiroWilk Royston Expanded Approximation
1763
- if(expanded || N > 50){
1764
- let u = 1/Math.sqrt(N);
1765
- let m_i: number[] = [];
1766
- let M = 0;
1767
- for(let i = 0; i < N; i++){
1768
- let m = Distributions.Normal.inv((i+1-0.375)/(N+.25));
1769
- m_i[i] = m;
1770
- M += Math.pow(m,2);
1771
- }
1772
-
1773
- let a_i: number[] = [];
1774
- a_i[N - 1] = -2.706056*Math.pow(u,5)+4.434685*Math.pow(u,4)-2.07119*Math.pow(u,3)-0.147981*Math.pow(u,2)+0.221157*u+m_i[N - 1]/Math.sqrt(M);
1775
- a_i[N - 2] = -3.582633*Math.pow(u,5)+5.682633*Math.pow(u,4)-1.752461*Math.pow(u,3)-0.293762*Math.pow(u,2)+0.042981*u+m_i[N - 2]/Math.sqrt(M);
1776
- a_i[0] = -1 * a_i[N-1];
1777
- a_i[1] = -1 * a_i[N-2];
1778
- let eps = (M-2*Math.pow(m_i[N-1],2)-2*Math.pow(m_i[N-2],2))/(1-2*Math.pow(a_i[N-1],2)-2*Math.pow(a_i[N-2],2))
1779
-
1780
- for(let i = 2; i < N-2; i++){
1781
- a_i[i] = m_i[i]/Math.sqrt(eps);
1782
- }
1783
-
1784
- let W = Math.pow(Correlate(a_i, sorted), 2);
1799
+ // ShapiroWilk
1800
+ let b = 0;
1801
+ for(let i = 0; i < Math.floor(N/2); i++){
1802
+ let a = Distributions.Normal.ShapiroWilk.constants[i][N-2];
1803
+ b += a*(invSort[i]-sorted[i]);
1804
+ }
1805
+ let W = Math.pow(b, 2)/SS;
1785
1806
 
1807
+ if(algorithmic){
1786
1808
  let p_mu = 0.0038915*Math.pow(Math.log(N),3)-0.083751*Math.pow(Math.log(N),2)-0.31082*Math.log(N)-1.5861;
1787
1809
  let p_sigma = Math.exp(0.0030302*Math.pow(Math.log(N),2)-0.082676*Math.log(N)-0.4803);
1788
1810
  let z = (Math.log(1 - W) - p_mu)/p_sigma;
1789
-
1811
+
1790
1812
  return {
1791
1813
  W: W,
1792
1814
  p: 1 - Distributions.Normal.cdf(z, 0, 1)
1793
1815
  }
1794
1816
  }
1795
- // ShapiroWilk
1796
- let b = 0;
1797
- for(let i = 0; i < Math.floor(N/2); i++){
1798
- let a = Distributions.Normal.ShapiroWilk.constants[i][N-2];
1799
- b += a*(invSort[i]-sorted[i]);
1800
- }
1801
- let W = Math.pow(b, 2)/SS;
1817
+
1802
1818
  let p = Distributions.Normal.ShapiroWilk.p(W, N);
1803
1819
  return {
1804
1820
  W: W,
@@ -3558,7 +3574,7 @@ export function CreateScatterPlot(data: DataSet[], title?: string, chartSettings
3558
3574
  * @param std Standard Deviation of Data
3559
3575
  * @param display Display settings for out-of-control points. DEFAULT: RED SQUARE
3560
3576
  */
3561
- function MarkOutOfControl(data: DataSet, UCL: number, LCL: number, CL?: any, std?: any, display = new CanvasDrawSettings("red", "black", 1, 1), controlTests: number[] = [1,2,3,4,5,6,7,8]) {
3577
+ function MarkOutOfControl(data: DataSet, UCL: number, LCL: number, CL?: any, std?: any, display = new CanvasDrawSettings("red", "red", 1, 1), controlTests: number[] = [1]) {
3562
3578
  if(CL === undefined){CL = Mean([LCL, UCL])}
3563
3579
  if(std === undefined){std = (CL - LCL)/3}
3564
3580
  let Test2 = 0;
@@ -3577,7 +3593,7 @@ function MarkOutOfControl(data: DataSet, UCL: number, LCL: number, CL?: any, std
3577
3593
  if(controlTests.includes(2) && ((v.y > CL && Test2 >= 0) || (v.y < CL && Test2 <= 0))){
3578
3594
  Test2 += v.y < CL ? -1 : 1;
3579
3595
  if(Test2 >= 8 || Test2 <= -8){
3580
- v.display = display;
3596
+ v.display = new CanvasDrawSettings("orange", "red", 1, 1);
3581
3597
  }
3582
3598
  }else{
3583
3599
  Test2 = 0;
@@ -3588,7 +3604,7 @@ function MarkOutOfControl(data: DataSet, UCL: number, LCL: number, CL?: any, std
3588
3604
  if(controlTests.includes(3) && ((v.y > data.values[i-1].y && Test3 >= 0) || (v.y < data.values[i-1].y && Test3 <= 0))){
3589
3605
  Test3 += v.y < data.values[i-1].y ? -1 : 1;
3590
3606
  if(Test3 >= 5 || Test3 <= -6){
3591
- v.display = display;
3607
+ v.display = new CanvasDrawSettings("yellow", "red", 1, 1);;
3592
3608
  }
3593
3609
  }else{
3594
3610
  Test3 = 0;
@@ -3600,7 +3616,7 @@ function MarkOutOfControl(data: DataSet, UCL: number, LCL: number, CL?: any, std
3600
3616
  Test4 = -1*(Test4 + 1);
3601
3617
  }else{Test4 = 0}
3602
3618
  if(Math.abs(Test4) >= 13){
3603
- v.display = display;
3619
+ v.display = new CanvasDrawSettings("purple", "red", 1, 1);;
3604
3620
  }
3605
3621
  }
3606
3622
  if(controlTests.includes(4) && v.y > data.values[i-1].y){
@@ -3608,7 +3624,7 @@ function MarkOutOfControl(data: DataSet, UCL: number, LCL: number, CL?: any, std
3608
3624
  Test4 = -1*(Test4 - 1);
3609
3625
  }else{Test4 = 0}
3610
3626
  if(Math.abs(Test4) >= 13){
3611
- v.display = display;
3627
+ v.display = new CanvasDrawSettings("purple", "red", 1, 1);;
3612
3628
  }
3613
3629
  }
3614
3630
  }
@@ -3619,7 +3635,7 @@ function MarkOutOfControl(data: DataSet, UCL: number, LCL: number, CL?: any, std
3619
3635
  if (controlTests.includes(5) && v.y > 2*std+CL) {
3620
3636
  Test5[2] = 1;
3621
3637
  if(Test5[0] === 1 || Test5[1] === 1){
3622
- v.display = display;
3638
+ v.display = new CanvasDrawSettings("white", "red", 1, 1);;
3623
3639
  }
3624
3640
  }
3625
3641
  if (controlTests.includes(5) && v.y < CL-2*std) {
@@ -3639,7 +3655,7 @@ function MarkOutOfControl(data: DataSet, UCL: number, LCL: number, CL?: any, std
3639
3655
  Test6[5] = 1;
3640
3656
  let plus = Test6.filter(t => t === 1);
3641
3657
  if(plus.length >= 4){
3642
- v.display = display
3658
+ v.display = new CanvasDrawSettings("grey", "red", 1, 1);
3643
3659
  }
3644
3660
  }else if (controlTests.includes(6) && v.y < CL-std) {
3645
3661
  Test6[5] = -1;
@@ -3653,17 +3669,17 @@ function MarkOutOfControl(data: DataSet, UCL: number, LCL: number, CL?: any, std
3653
3669
  if(controlTests.includes(7) && v.y >= CL - std && v.y <= CL + std){
3654
3670
  Test7 += 1;
3655
3671
  if(Test7 >= 15){
3656
- v.display = display;
3672
+ v.display = new CanvasDrawSettings("pink", "red", 1, 1);;
3657
3673
  }
3658
3674
  }else{
3659
3675
  Test7 = 0
3660
3676
  }
3661
3677
 
3662
- // Test7: Fifteen points in a row within 1σ of center line (either side)
3678
+ // Test8: Fifteen points in a row within 1σ of center line (either side)
3663
3679
  if(controlTests.includes(8) && (v.y < CL - std || v.y > CL + std)){
3664
3680
  Test8 += 1;
3665
3681
  if(Test8 >= 8){
3666
- v.display = display;
3682
+ v.display = new CanvasDrawSettings("brown", "red", 1, 1);;
3667
3683
  }
3668
3684
  }else{
3669
3685
  Test8 = 0
@@ -4149,12 +4165,20 @@ export function QQPlotChart(data: number[], distribution: string = 'Normal'){
4149
4165
 
4150
4166
  if (distribution.toLowerCase() === "normal" || distribution.toLowerCase().includes("boxcox")) {
4151
4167
  let AD = GoodnessOfFit.AndersonDarling.Test(data, GoodnessOfFit.Distributions.Normal);
4152
- let RJ = Distributions.Normal.RyanJoiner.Test(data);
4153
- let KS = Distributions.Normal.KolmogorovSmirnov(data);
4154
4168
  let JB = Distributions.Normal.JarqueBera(data);
4169
+ let KS = Distributions.Normal.KolmogorovSmirnov(data);
4170
+ let LF = Distributions.Normal.Lilliefors.Test(data);
4171
+ let RJ = Distributions.Normal.RyanJoiner.Test(data);
4172
+ let SWR = Distributions.Normal.ShapiroWilk.Royston(data);
4155
4173
  let ctx = chart.getContext("2d");
4156
4174
  if(ctx){
4157
- AddInfoTable(ctx, [{ key: "AD:", value: AD.AD }, { key: "p-value:", value: AD.p }, { key: "", value: '' }, { key: "RJ:", value: RJ.RJ }, { key: "crit.:", value: RJ.critical }, { key: "", value: "" }, { key: "KS:", value: KS.KS }, { key: "p-value:", value: KS.p }, { key: "", value: "" }, { key: "JB:", value: JB.JB }, { key: "p-value:", value: JB.p }], 1075, 150, 175, 100, "", 30);
4175
+ AddInfoTable(ctx, [
4176
+ { key: "AD:", value: AD.AD }, { key: "p-value:", value: AD.p }, { key: "", value: '' },
4177
+ { key: "JB:", value: JB.JB }, { key: "p-value:", value: JB.p }, { key: "", value: "" },
4178
+ { key: "KS:", value: KS.KS }, { key: "p-value:", value: KS.p }, { key: "", value: "" },
4179
+ { key: "Lf:", value: LF.KS }, { key: "p-value:", value: LF.p }, { key: "", value: "" },
4180
+ { key: "RJ:", value: RJ.RJ }, { key: "crit.:", value: RJ.critical }, { key: "", value: "" },
4181
+ { key: "SW(R):", value: SWR.W }, { key: "p-value:", value: SWR.p }, { key: "", value: "" },], 1075, 150, 175, 100, "", 30);
4158
4182
  }
4159
4183
  }else{
4160
4184
  let dist = distribution.replace("-", "").replace("arameter", "").replace(/\s/g, "");
@@ -4222,7 +4246,7 @@ function QQDistributionModificationX(p: number, distribution: string, data: numb
4222
4246
  return p;
4223
4247
  }
4224
4248
 
4225
- function CreateControlChart(data: number[], chartTitle?: string, UCL?: number, LCL?: number){
4249
+ export function CreateControlChart(data: number[], chartTitle?: string, UCL?: number, LCL?: number){
4226
4250
  let centerline = Mean(data);
4227
4251
  let std = StDev.S(data);
4228
4252
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qesuite",
3
- "version": "1.0.36",
3
+ "version": "1.0.38",
4
4
  "description": "Performs advanced statistical analysis of data. Specifically designed for engineering statistical analysis",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -0,0 +1,14 @@
1
+ - Separated RoystonShapiroWilk from ShapiroWilk.Test()
2
+ - - ShapiroWilk.Test() can now evaluate p-value using the approximately normal distribution of the p-value using ln(1-W)
3
+ - - ShapiroWilk.Royston() performs Royston Expanded test
4
+
5
+ - Control Chart Tests are now identified by the color of the point fill
6
+ - Test 1: red
7
+ - Test 2: orange
8
+ - Test 3: yellow
9
+ - Test 4: purple
10
+ - Test 5: black
11
+ - Test 6: grey
12
+ - Test 7: pink
13
+ - Test 8: brown
14
+ - Control chart defaults to only perform test 1
@@ -0,0 +1,3 @@
1
+ - include export for CreateControlChart();
2
+ - include Shapiro-Wilk (Royston) and Lilliefors in QQPlot for normality
3
+ - alphabetized the order of normality results table on QQPlot by test name