Contact Support
Create a control chart
28 Feb 202224 minutes to read
You can create a control chart (with UCL, CL, and LCL limits) using the stripline and annotation features.
To create a control charts, follow the given steps.
Step 1: Load line charts for the data.
@(Html.EJS().Chart("container").Title("Sales History of Product X").Load("load").Loaded("loaded").PointRender("pointRender").Series(series =>
{
series.Type(Syncfusion.EJ2.Charts.ChartSeriesType.Line).
XName("xValue").
YName("yValue").
Marker(mr => mr.Visible(true).Height(10).Width(10)).
DataSource(ViewBag.dataSource).Add();
}).
PrimaryXAxis(px => px.ValueType(Syncfusion.EJ2.Charts.ValueType.DateTime).MajorGridLines(mg => mg.Width(0)).MajorTickLines(mt => mt.Width(0)))
.PrimaryYAxis(py => py.MajorGridLines(mg => mg.Width(0)).MajorTickLines(mt => mt.Width(0)))
.Render()
)
public IActionResult Index()
{
List<LineChartData> chartData = new List<LineChartData>
{
new LineChartData { xValue = new DateTime(1975, 01, 01), yValue = 36},
new LineChartData { xValue = new DateTime(1980, 01, 01), yValue = 32.5 },
new LineChartData { xValue = new DateTime(1985, 01, 01), yValue = 39 },
new LineChartData { xValue = new DateTime(1990, 01, 01), yValue = 34.4 },
new LineChartData { xValue = new DateTime(1995, 01, 01), yValue = 31.5 },
new LineChartData { xValue = new DateTime(2000, 01, 01), yValue = 40 },
new LineChartData { xValue = new DateTime(2005, 01, 01), yValue = 60 },
new LineChartData { xValue = new DateTime(2010, 01, 01), yValue = 66 },
};
ViewBag.dataSource = chartData;
ViewBag.line = new { width = 0.0001 };
return View();
}
public class LineChartData
{
public DateTime xValue;
public double yValue;
}
Step 2: Now, add three striplines for three control limits: LCL, UCL, and CL.
@(Html.EJS().Chart("container").Title("Sales History of Product X").Load("load").Loaded("loaded").PointRender("pointRender").Series(series =>
{
series.Type(Syncfusion.EJ2.Charts.ChartSeriesType.Line).
XName("xValue").
YName("yValue").
Marker(mr => mr.Visible(true).Height(10).Width(10)).
DataSource(ViewBag.dataSource).Add();
}).
PrimaryXAxis(px => px.ValueType(Syncfusion.EJ2.Charts.ValueType.DateTime).MajorGridLines(mg => mg.Width(0)).MajorTickLines(mt => mt.Width(0)))
.PrimaryYAxis(py => py.MajorGridLines(mg => mg.Width(0)).MajorTickLines(mt => mt.Width(0)).StripLines(ViewBag.yAxisStripLine))
.Render()
)
public IActionResult Index()
{
List<LineChartData> chartData = new List<LineChartData>
{
new LineChartData { xValue = new DateTime(1975, 01, 01), yValue = 36},
new LineChartData { xValue = new DateTime(1980, 01, 01), yValue = 32.5 },
new LineChartData { xValue = new DateTime(1985, 01, 01), yValue = 39 },
new LineChartData { xValue = new DateTime(1990, 01, 01), yValue = 34.4 },
new LineChartData { xValue = new DateTime(1995, 01, 01), yValue = 31.5 },
new LineChartData { xValue = new DateTime(2000, 01, 01), yValue = 40 },
new LineChartData { xValue = new DateTime(2005, 01, 01), yValue = 60 },
new LineChartData { xValue = new DateTime(2010, 01, 01), yValue = 66 },
};
ViewBag.dataSource = chartData;
ViewBag.line = new { width = 0.0001 };
List<ChartStripLine> yAxisStripline = new List<ChartStripLine>();
ChartStripLine ystripline1 = new ChartStripLine();
ystripline1.Start = "30";
ystripline1.End = "40";
ystripline1.Text = "";
ystripline1.Color = "black";
ystripline1.Visible = true;
ChartStripLine ystripline2 = new ChartStripLine();
ystripline2.Start = "20";
ystripline2.End = "30";
ystripline2.Text = "";
ystripline2.Color = "black";
ystripline2.Visible = true;
ChartStripLine ystripline3 = new ChartStripLine();
ystripline3.Start = "10";
ystripline3.End = "20";
ystripline3.Text = "";
ystripline3.Color = "black";
ystripline3.Visible = true;
yAxisStripline.Add(ystripline1);
yAxisStripline.Add(ystripline2);
yAxisStripline.Add(ystripline3);
ViewBag.yAxisStripLine = yAxisStripline;
return View();
}
public class LineChartData
{
public DateTime xValue;
public double yValue;
}
Step 3: Then, add annotations to show the text for LCL, UCL, and CL in respective positions.
<ejs-chart id="container" title="Sales History of Product X">
<e-chart-primaryxaxis valueType="DateTime" majorGridLines="ViewBag.line" majorTickLines="ViewBag.line"></e-chart-primaryxaxis>
<e-chart-primaryyaxis stripLines="ViewBag.yAxisStripLine" majorGridLines="ViewBag.line" majorTickLines="ViewBag.line"></e-chart-primaryyaxis>
<e-series-collection>
<e-series dataSource="ViewBag.dataSource" xName="xValue" yName="yValue" type="@Syncfusion.EJ2.Charts.ChartSeriesType.Line">
<e-series-marker visible="true" height="10" width="10"></e-series-marker>
</e-series>
</e-series-collection>
<e-chart-annotations>
<e-chart-annotation Content="<div>LCL</div>" X="30" Y="2" CoordinateUnits='@Syncfusion.EJ2.Charts.Units.Point'></e-chart-annotation>
<e-chart-annotation Content="<div>CL</div>" X="30" Y="2" CoordinateUnits='@Syncfusion.EJ2.Charts.Units.Point'></e-chart-annotation>
<e-chart-annotation Content="<div>UCL</div>" X="30" Y="2" CoordinateUnits='@Syncfusion.EJ2.Charts.Units.Point'></e-chart-annotation>
<e-chart-annotation Content="<div>Number of groups: xx</div><div>CL: xx</div><div>LCL: xx</div><div>UCL: xx</div><div>Standard Divation: xx</div>" X="400" Y="500" CoordinateUnits='@Syncfusion.EJ2.Charts.Units.Pixel'></e-chart-annotation>
</e-chart-annotations>
</ejs-chart>
Step 4: Calculate the control limits based on the CL, LCL, and UCL. The start and end ranges have been set for strip lines in the load event.
<script>
var mean = 0, LCL = 0, UCL = 0, s = 0;
function load(args) {
// calculate the mean value
for (var i = 0; i < args.chart.series[0].dataSource.length; i++) {
mean = (mean) + (+args.chart.series[0].dataSource[i].yValue);
}
mean = mean / args.chart.series[0].dataSource.length;
for (var i = 0; i < args.chart.series[0].dataSource.length; i++) {
s += ((+args.chart.series[0].dataSource[i].yValue) - mean) * ((+args.chart.series[0].dataSource[i].yValue) - mean);
}
// calculate the standard divation here
s = s / args.chart.series[0].dataSource.length;
s = Math.sqrt(s);
// Calculate LCL and UCL
LCL = mean - (1.5 * s);
UCL = mean + (1.5 * s);
// set the strip line ranges based on the LCL and UCL
args.chart.primaryYAxis.stripLines[0].start = LCL;
args.chart.primaryYAxis.stripLines[0].end = LCL + 0.0125;
args.chart.primaryYAxis.stripLines[1].start = mean;
args.chart.primaryYAxis.stripLines[1].end = mean + 0.25;
args.chart.primaryYAxis.stripLines[2].start = UCL;
args.chart.primaryYAxis.stripLines[2].end = UCL + 0.0135;
}
</script>
Step 5: Highlight the points that are above the UCL using the pointRender event.
<script>
function pointRender(args) {
if (args.point.y > UCL) {
args.fill = 'red';
}
}
</script>
Step 6: Change the values of annotation text (UCL, LCL, mean, and CL).
<script>
var mean = 0, LCL = 0, UCL = 0, s = 0;
function load(args) {
// calculate the mean value
for (var i = 0; i < args.chart.series[0].dataSource.length; i++) {
mean = (mean) + (+args.chart.series[0].dataSource[i].yValue);
}
mean = mean / args.chart.series[0].dataSource.length;
for (var i = 0; i < args.chart.series[0].dataSource.length; i++) {
s += ((+args.chart.series[0].dataSource[i].yValue) - mean) * ((+args.chart.series[0].dataSource[i].yValue) - mean);
}
// calculate the standard divation here
s = s / args.chart.series[0].dataSource.length;
s = Math.sqrt(s);
// Calculate LCL and UCL
LCL = mean - (1.5 * s);
UCL = mean + (1.5 * s);
// set the annotations x and y positions based on the LCL and UCL
args.chart.annotations[0].x = args.chart.series[0].dataSource[args.chart.series[0].dataSource.length - 1].xValue;
args.chart.annotations[0].y = LCL;
args.chart.annotations[1].x = args.chart.series[0].dataSource[args.chart.series[0].dataSource.length - 1].xValue;
args.chart.annotations[1].y = mean;
args.chart.annotations[2].x = args.chart.series[0].dataSource[args.chart.series[0].dataSource.length - 1].xValue;
args.chart.annotations[2].y = UCL;
}
</script>
Step 7: Add the dasharray for stripline elements and add some pixel for the annotation elements to move from its default position and then add the text for the last annotation to show the mean, UCL, CL, LCL and standard divation in the loaded event.
<script>
function loaded(args) {
// Add dasharray for strip line elements
var strip1 = document.getElementById('container_stripline_Behind_rect_0');
strip1.setAttribute('stroke', 'black');
strip1.setAttribute('stroke-dasharray', '5');
var strip2 = document.getElementById('container_stripline_Behind_rect_2');
strip2.setAttribute('stroke', 'black');
strip2.setAttribute('stroke-dasharray', '5');
var annotation = document.getElementById('container_Annotation_Collections');
var child, left;
// move the annotation elements to nearest chart area by adding some pixel to annotation elements
for (var i = 0; i < annotation.children.length - 1; i++) {
child = annotation.children[i];
left = child.style.left;
left = +(left.replace('px', '')) + 20;
child.style.left = left + 'px';
}
// Add the annotation text to show the mean, UCL, CL, LCL and standard divation
annotation.children[3].children[0].innerText = annotation.children[3].children[0].innerText.replace('xx', args.chart.series[0].dataSource.length);
annotation.children[3].children[1].innerText = annotation.children[3].children[1].innerText.replace('xx', mean);
annotation.children[3].children[2].innerText = annotation.children[3].children[2].innerText.replace('xx', LCL);
annotation.children[3].children[3].innerText = annotation.children[3].children[3].innerText.replace('xx', UCL);
annotation.children[3].children[4].innerText = annotation.children[3].children[4].innerText.replace('xx', s);
}
</script>
@(Html.EJS().Chart("container").Title("Sales History of Product X").Load("load").Loaded("loaded").PointRender("pointRender").Series(series =>
{
series.Type(Syncfusion.EJ2.Charts.ChartSeriesType.Line).
XName("xValue").
YName("yValue").
Marker(mr => mr.Visible(true).Height(10).Width(10)).
DataSource(ViewBag.dataSource).Add();
}).Annotations(an =>
{
an.X("30").Y("2").CoordinateUnits(Syncfusion.EJ2.Charts.Units.Point).Content("<div>LCL</div>").Add();
an.X("30").Y("2").CoordinateUnits(Syncfusion.EJ2.Charts.Units.Point).Content("<div>CL</div>").Add();
an.X("30").Y("2").CoordinateUnits(Syncfusion.EJ2.Charts.Units.Point).Content("<div>UCL</div>").Add();
an.X("400").Y("500").CoordinateUnits(Syncfusion.EJ2.Charts.Units.Point).Content("<div>Number of groups: xx</div><div>CL: xx</div><div>LCL: xx</div><div>UCL: xx</div><div>Standard Divation: xx</div>").Add();
}).
PrimaryXAxis(px => px.ValueType(Syncfusion.EJ2.Charts.ValueType.DateTime).MajorGridLines(mg => mg.Width(0)).MajorTickLines(mt => mt.Width(0)))
.PrimaryYAxis(py => py.MajorGridLines(mg => mg.Width(0)).MajorTickLines(mt => mt.Width(0)).StripLines(ViewBag.yAxisStripLine))
.Render()
)
<script>
var mean = 0, LCL = 0, UCL = 0, s = 0;
function load(args) {
// calculate the mean value
for (var i = 0; i < args.chart.series[0].dataSource.length; i++) {
mean = (mean) + (+args.chart.series[0].dataSource[i].yValue);
}
mean = mean / args.chart.series[0].dataSource.length;
for (var i = 0; i < args.chart.series[0].dataSource.length; i++) {
s += ((+args.chart.series[0].dataSource[i].yValue) - mean) * ((+args.chart.series[0].dataSource[i].yValue) - mean);
}
// calculate the standard divation here
s = s / args.chart.series[0].dataSource.length;
s = Math.sqrt(s);
// Calculate LCL and UCL
LCL = mean - (1.5 * s);
UCL = mean + (1.5 * s);
// set the strip line ranges based on the LCL and UCL
args.chart.primaryYAxis.stripLines[0].start = LCL;
args.chart.primaryYAxis.stripLines[0].end = LCL + 0.0125;
args.chart.primaryYAxis.stripLines[1].start = mean;
args.chart.primaryYAxis.stripLines[1].end = mean + 0.25;
args.chart.primaryYAxis.stripLines[2].start = UCL;
args.chart.primaryYAxis.stripLines[2].end = UCL + 0.0135;
args.chart.annotations[0].x = args.chart.series[0].dataSource[args.chart.series[0].dataSource.length - 1].xValue;
args.chart.annotations[0].y = LCL;
args.chart.annotations[1].x = args.chart.series[0].dataSource[args.chart.series[0].dataSource.length - 1].xValue;
args.chart.annotations[1].y = mean;
args.chart.annotations[2].x = args.chart.series[0].dataSource[args.chart.series[0].dataSource.length - 1].xValue;
args.chart.annotations[2].y = UCL;
}
function loaded(args) {
var strip1 = document.getElementById('container_stripline_Behind_rect_primaryYAxis_0');
strip1.setAttribute('stroke', 'black');
strip1.setAttribute('stroke-dasharray', '5');
var strip2 = document.getElementById('container_stripline_Behind_rect_primaryYAxis_0');
strip2.setAttribute('stroke', 'black');
strip2.setAttribute('stroke-dasharray', '5');
var annotation = document.getElementById('container_Annotation_Collections');
var child, left;
for (var i = 0; i < annotation.children.length - 1; i++) {
child = annotation.children[i];
left = child.style.left;
left = +(left.replace('px', '')) + 20;
child.style.left = left + 'px';
}
annotation.children[3].children[0].innerText = annotation.children[3].children[0].innerText.replace('xx', args.chart.series[0].dataSource.length);
annotation.children[3].children[1].innerText = annotation.children[3].children[1].innerText.replace('xx', mean);
annotation.children[3].children[2].innerText = annotation.children[3].children[2].innerText.replace('xx', LCL);
annotation.children[3].children[3].innerText = annotation.children[3].children[3].innerText.replace('xx', UCL);
annotation.children[3].children[4].innerText = annotation.children[3].children[4].innerText.replace('xx', s);
}
function pointRender(args) {
if (args.point.y > UCL) {
args.fill = 'red';
}
}
</script>
public IActionResult Index()
{
List<LineChartData> chartData = new List<LineChartData>
{
new LineChartData { xValue = new DateTime(1975, 01, 01), yValue = 36},
new LineChartData { xValue = new DateTime(1980, 01, 01), yValue = 32.5 },
new LineChartData { xValue = new DateTime(1985, 01, 01), yValue = 39 },
new LineChartData { xValue = new DateTime(1990, 01, 01), yValue = 34.4 },
new LineChartData { xValue = new DateTime(1995, 01, 01), yValue = 31.5 },
new LineChartData { xValue = new DateTime(2000, 01, 01), yValue = 40 },
new LineChartData { xValue = new DateTime(2005, 01, 01), yValue = 60 },
new LineChartData { xValue = new DateTime(2010, 01, 01), yValue = 66 },
};
ViewBag.dataSource = chartData;
List<ChartStripLine> yAxisStripline = new List<ChartStripLine>();
ChartStripLine ystripline1 = new ChartStripLine();
ystripline1.Start = "30";
ystripline1.End = "40";
ystripline1.Text = "";
ystripline1.Color = "black";
ystripline1.Visible = true;
ChartStripLine ystripline2 = new ChartStripLine();
ystripline2.Start = "20";
ystripline2.End = "30";
ystripline2.Text = "";
ystripline2.Color = "black";
ystripline2.Visible = true;
ChartStripLine ystripline3 = new ChartStripLine();
ystripline3.Start = "10";
ystripline3.End = "20";
ystripline3.Text = "";
ystripline3.Color = "black";
ystripline3.Visible = true;
yAxisStripline.Add(ystripline1);
yAxisStripline.Add(ystripline2);
yAxisStripline.Add(ystripline3);
ViewBag.yAxisStripLine = yAxisStripline;
return View();
}
public class LineChartData
{
public DateTime xValue;
public double yValue;
}
Screenshots:
Sample link: A sample for creating control chart is available in the following link, chartSample
.