javascriptd3.jsvega-litevegavega-lite-api

Vega lite api miss-behaving


I prepared this vegalite visualization:

data = [{"student_name": "student 0", "e": "100.15", "d": "127.81"}, {"student_name": "student 1", "e": "100.30", "d": "189.94"}, {"student_name": "student 2", "e": "100.15", "d": "105.33"}, {"student_name": "student 3", "e": "99.41", "d": "85.36"}, {"student_name": "student 4", "e": "100.00", "d": "203.70"}, {"student_name": "student 5", "e": "100.15", "d": "139.05"}, {"student_name": "student 6", "e": "41.72", "d": "41.72"}, {"student_name": "student 7", "e": "100.30", "d": "260.50"}, {"student_name": "student 8", "e": "92.60", "d": "94.53"}, {"student_name": "student 9", "e": "99.11", "d": "86.39"}, {"student_name": "student 10", "e": "97.49", "d": "92.46"}, {"student_name": "student 11", "e": "98.37", "d": "83.58"}, {"student_name": "student 12", "e": "100.15", "d": "182.40"}, {"student_name": "student 13", "e": "100.15", "d": "99.41"}, {"student_name": "student 14", "e": "86.69", "d": "81.95"}, {"student_name": "student 15", "e": "98.08", "d": "306.51"}, {"student_name": "student 16", "e": "100.15", "d": "86.54"}, {"student_name": "student 17", "e": "100.15", "d": "186.39"}, {"student_name": "student 18", "e": "99.26", "d": "93.64"}, {"student_name": "student 19", "e": "100.15", "d": "102.66"}, {"student_name": "student 20", "e": "95.71", "d": "52.96"}, {"student_name": "student 21", "e": "99.85", "d": "99.41"}, {"student_name": "student 22", "e": "98.96", "d": "100.44"}, {"student_name": "student 23", "e": "100.15", "d": "131.07"}, {"student_name": "student 24", "e": "99.56", "d": "76.92"}, {"student_name": "student 25", "e": "100.15", "d": "213.46"}, {"student_name": "student 26", "e": "100.15", "d": "311.24"}, {"student_name": "student 27", "e": "100.15", "d": "21.89"}, {"student_name": "student 28", "e": "96.60", "d": "6.36"}, {"student_name": "student 29", "e": "53.70", "d": "3.70"}, {"student_name": "student 30", "e": "96.75", "d": "46.60"}, {"student_name": "student 31", "e": "100.15", "d": "100.15"}, {"student_name": "student 32", "e": "100.30", "d": "115.68"}, {"student_name": "student 33", "e": "87.13", "d": "103.85"}, {"student_name": "student 34", "e": "100.15", "d": "104.14"}, {"student_name": "student 35", "e": "99.26", "d": "59.17"}, {"student_name": "student 36", "e": "100.15", "d": "171.30"}, {"student_name": "student 37", "e": "99.11", "d": "94.08"}, {"student_name": "student 38", "e": "81.66", "d": "57.40"}, {"student_name": "student 39", "e": "96.01", "d": "154.59"}, {"student_name": "student 40", "e": "98.96", "d": "79.29"}, {"student_name": "student 41", "e": "99.26", "d": "118.20"}, {"student_name": "student 42", "e": "100.15", "d": "130.92"}, {"student_name": "student 43", "e": "90.53", "d": "47.63"}, {"student_name": "student 44", "e": "100.15", "d": "146.75"}, {"student_name": "student 45", "e": "96.01", "d": "197.63"}, {"student_name": "student 46", "e": "100.15", "d": "100.15"}, {"student_name": "student 47", "e": "107.25", "d": "115.24"}, {"student_name": "student 48", "e": "98.67", "d": "48.37"}, {"student_name": "student 49", "e": "88.61", "d": "190.53"}, {"student_name": "student 50", "e": "100.30", "d": "104.44"}, {"student_name": "student 51", "e": "51.18", "d": "51.18"}, {"student_name": "student 52", "e": "93.64", "d": "19.08"}, {"student_name": "student 53", "e": "100.00", "d": "123.08"}, {"student_name": "student 54", "e": "98.67", "d": "103.25"}, {"student_name": "student 55", "e": "98.37", "d": "95.86"}, {"student_name": "student 56", "e": "100.30", "d": "129.44"}, {"student_name": "student 57", "e": "100.15", "d": "164.50"}, {"student_name": "student 58", "e": "100.15", "d": "340.24"}, {"student_name": "student 59", "e": "100.30", "d": "165.83"}, {"student_name": "student 60", "e": "100.15", "d": "203.99"}, {"student_name": "student 61", "e": "92.75", "d": "160.06"}, {"student_name": "student 62", "e": "99.26", "d": "58.28"}, {"student_name": "student 63", "e": "99.41", "d": "99.41"}, {"student_name": "student 64", "e": "50.30", "d": "50.30"}, {"student_name": "student 65", "e": "93.79", "d": "50.30"}, {"student_name": "student 66", "e": "100.15", "d": "178.40"}, {"student_name": "student 67", "e": "99.11", "d": "6.21"}, {"student_name": "student 68", "e": "100.15", "d": "211.09"}, {"student_name": "student 69", "e": "100.15", "d": "69.08"}, {"student_name": "student 70", "e": "97.63", "d": "110.50"}, {"student_name": "student 71", "e": "100.15", "d": "126.33"}, {"student_name": "student 72", "e": "97.34", "d": "78.85"}, {"student_name": "student 73", "e": "100.15", "d": "182.99"}, {"student_name": "student 74", "e": "97.34", "d": "53.99"}, {"student_name": "student 75", "e": "98.22", "d": "45.12"}, {"student_name": "student 76", "e": "100.00", "d": "136.69"}, {"student_name": "student 77", "e": "98.82", "d": "41.72"}, {"student_name": "student 78", "e": "96.89", "d": "77.37"}, {"student_name": "student 79", "e": "97.78", "d": "81.36"}, {"student_name": "student 80", "e": "98.96", "d": "146.30"}, {"student_name": "student 81", "e": "99.26", "d": "48.67"}, {"student_name": "student 82", "e": "100.30", "d": "205.33"}, {"student_name": "student 83", "e": "98.82", "d": "141.42"}, {"student_name": "student 84", "e": "97.78", "d": "128.99"}, {"student_name": "student 85", "e": "100.15", "d": "86.69"}, {"student_name": "student 86", "e": "95.86", "d": "121.15"}, {"student_name": "student 87", "e": "97.49", "d": "88.31"}, {"student_name": "student 88", "e": "55.77", "d": "56.80"}, {"student_name": "student 89", "e": "96.01", "d": "13.17"}, {"student_name": "student 90", "e": "1.04", "d": "1.33"}, {"student_name": "student 91", "e": "99.70", "d": "26.18"}, {"student_name": "student 92", "e": "96.30", "d": "78.11"}, {"student_name": "student 93", "e": "99.85", "d": "11.83"}, {"student_name": "student 94", "e": "100.15", "d": "172.93"}, {"student_name": "student 95", "e": "100.00", "d": "198.82"}, {"student_name": "student 96", "e": "100.15", "d": "155.92"}, {"student_name": "student 97", "e": "92.01", "d": "97.19"}, {"student_name": "student 98", "e": "98.52", "d": "71.30"}, {"student_name": "student 99", "e": "100.15", "d": "111.69"}, {"student_name": "student 100", "e": "0.30", "d": "0.30"}, {"student_name": "student 101", "e": "91.72", "d": "86.54"}, {"student_name": "student 102", "e": "99.11", "d": "113.76"}, {"student_name": "student 103", "e": "98.22", "d": "67.75"}, {"student_name": "student 104", "e": "95.86", "d": "124.56"}, {"student_name": "student 105", "e": "105.92", "d": "201.48"}, {"student_name": "student 106", "e": "66.72", "d": "69.23"}, {"student_name": "student 107", "e": "100.15", "d": "151.18"}, {"student_name": "student 108", "e": "98.96", "d": "46.15"}, {"student_name": "student 109", "e": "100.15", "d": "160.36"}, {"student_name": "student 110", "e": "98.82", "d": "69.67"}, {"student_name": "student 111", "e": "98.08", "d": "80.03"}, {"student_name": "student 112", "e": "97.63", "d": "45.27"}, {"student_name": "student 113", "e": "96.60", "d": "37.28"}, {"student_name": "student 114", "e": "100.15", "d": "285.06"}, {"student_name": "student 115", "e": "98.96", "d": "77.81"}, {"student_name": "student 116", "e": "100.15", "d": "104.14"}, {"student_name": "student 117", "e": "100.15", "d": "160.65"}, {"student_name": "student 118", "e": "80.47", "d": "80.47"}, {"student_name": "student 119", "e": "100.15", "d": "115.09"}, {"student_name": "student 120", "e": "50.44", "d": "50.44"}, {"student_name": "student 121", "e": "100.15", "d": "136.83"}, {"student_name": "student 122", "e": "93.34", "d": "53.99"}, {"student_name": "student 123", "e": "100.15", "d": "136.09"}, {"student_name": "student 124", "e": "100.15", "d": "126.78"}, {"student_name": "student 125", "e": "89.35", "d": "74.85"}, {"student_name": "student 126", "e": "100.15", "d": "113.17"}, {"student_name": "student 127", "e": "97.78", "d": "78.25"}, {"student_name": "student 128", "e": "94.67", "d": "28.25"}, {"student_name": "student 129", "e": "100.15", "d": "154.88"}, {"student_name": "student 130", "e": "80.47", "d": "101.78"}, {"student_name": "student 131", "e": "99.11", "d": "66.42"}, {"student_name": "student 132", "e": "103.40", "d": "260.50"}, {"student_name": "student 133", "e": "99.11", "d": "17.75"}, {"student_name": "student 134", "e": "86.98", "d": "89.94"}, {"student_name": "student 135", "e": "96.30", "d": "81.66"}, {"student_name": "student 136", "e": "100.15", "d": "60.36"}, {"student_name": "student 137", "e": "100.15", "d": "73.52"}, {"student_name": "student 138", "e": "96.45", "d": "68.93"}, {"student_name": "student 139", "e": "100.30", "d": "165.83"}, {"student_name": "student 140", "e": "96.89", "d": "55.77"}, {"student_name": "student 141", "e": "100.15", "d": "112.72"}, {"student_name": "student 142", "e": "99.26", "d": "204.88"}, {"student_name": "student 143", "e": "100.15", "d": "356.51"}, {"student_name": "student 144", "e": "99.70", "d": "152.66"}, {"student_name": "student 145", "e": "100.15", "d": "40.83"}, {"student_name": "student 146", "e": "92.16", "d": "63.46"}, {"student_name": "student 147", "e": "100.15", "d": "179.88"}, {"student_name": "student 148", "e": "100.00", "d": "81.36"}, {"student_name": "student 149", "e": "16.57", "d": "11.98"}, {"student_name": "student 150", "e": "84.62", "d": "73.08"}, {"student_name": "student 151", "e": "100.59", "d": "100.59"}, {"student_name": "student 152", "e": "98.82", "d": "104.88"}, {"student_name": "student 153", "e": "99.11", "d": "135.95"}, {"student_name": "student 154", "e": "97.93", "d": "35.95"}, {"student_name": "student 155", "e": "100.15", "d": "101.92"}, {"student_name": "student 156", "e": "100.30", "d": "120.86"}, {"student_name": "student 157", "e": "81.07", "d": "88.76"}, {"student_name": "student 158", "e": "100.15", "d": "128.40"}, {"student_name": "student 159", "e": "94.67", "d": "119.23"}, {"student_name": "student 160", "e": "100.30", "d": "253.85"}, {"student_name": "student 161", "e": "91.42", "d": "68.05"}, {"student_name": "student 162", "e": "100.15", "d": "118.79"}, {"student_name": "student 163", "e": "100.15", "d": "101.04"}, {"student_name": "student 164", "e": "100.30", "d": "203.11"}, {"student_name": "student 165", "e": "100.59", "d": "155.18"}, {"student_name": "student 166", "e": "96.89", "d": "84.76"}, {"student_name": "student 167", "e": "100.15", "d": "115.38"}, {"student_name": "student 168", "e": "100.00", "d": "179.73"}, {"student_name": "student 169", "e": "100.15", "d": "135.65"}, {"student_name": "student 170", "e": "98.37", "d": "93.34"}, {"student_name": "student 171", "e": "100.15", "d": "128.40"}, {"student_name": "student 172", "e": "100.44", "d": "164.05"}, {"student_name": "student 173", "e": "98.37", "d": "57.54"}, {"student_name": "student 174", "e": "96.75", "d": "118.05"}, {"student_name": "student 175", "e": "98.96", "d": "91.12"}, {"student_name": "student 176", "e": "100.00", "d": "226.04"}, {"student_name": "student 177", "e": "98.67", "d": "150.89"}, {"student_name": "student 178", "e": "97.49", "d": "68.79"}, {"student_name": "student 179", "e": "100.15", "d": "133.58"}, {"student_name": "student 180", "e": 0, "d": 0}, {"student_name": "student 181", "e": 0, "d": 0}, {"student_name": "student 182", "e": 0, "d": 0}, {"student_name": "student 183", "e": 0, "d": 0}, {"student_name": "student 184", "e": 0, "d": 0}, {"student_name": "student 185", "e": 0, "d": 0}, {"student_name": "student 186", "e": 0, "d": 0}, {"student_name": "student 187", "e": 0, "d": 0}, {"student_name": "student 188", "e": 0, "d": 0}, {"student_name": "student 189", "e": 0, "d": 0}, {"student_name": "student 190", "e": 0, "d": 0}, {"student_name": "student 191", "e": 0, "d": 0}, {"student_name": "student 192", "e": 0, "d": 0}, {"student_name": "student 193", "e": 0, "d": 0}, {"student_name": "student 194", "e": 0, "d": 0}, {"student_name": "student 195", "e": 0, "d": 0}, {"student_name": "student 196", "e": 0, "d": 0}, {"student_name": "student 197", "e": 0, "d": 0}, {"student_name": "student 198", "e": 0, "d": 0}, {"student_name": "student 199", "e": 0, "d": 0}, {"student_name": "student 200", "e": 0, "d": 0}, {"student_name": "student 201", "e": 0, "d": 0}, {"student_name": "student 202", "e": 0, "d": 0}, {"student_name": "student 203", "e": 0, "d": 0}, {"student_name": "student 204", "e": 0, "d": 0}, {"student_name": "student 205", "e": 0, "d": 0}, {"student_name": "student 206", "e": 0, "d": 0}, {"student_name": "student 207", "e": 0, "d": 0}, {"student_name": "student 208", "e": 0, "d": 0}, {"student_name": "student 209", "e": 0, "d": 0}, {"student_name": "student 210", "e": 0, "d": 0}, {"student_name": "student 211", "e": 0, "d": 0}]

createChart = function (data) {
  max_d = d3.max(data, record => parseFloat(record.d));
  max_e = d3.max(data, record => parseFloat(record.e));
  max_y_scale_value_for_d = d3.max([100, max_d]);
  max_y_scale_value_for_e = d3.max([100, max_e]);

  const mpg = vl.markLine()
              .data(data)
              .transform([{ "calculate": "toNumber(datum.d)", "as": "d2" }, { "calculate": "toNumber(datum.e)", "as": "e2" }])
              
              .encode(
                      vl.x()
                        .fieldN('student_name')
                        .title('students')
                        .axis({ labels: false, ticks: false })
                        .sort('-y'),
                      vl.y()
                        .fieldQ('d2')
                        .scale({ "domain": [0, max_y_scale_value_for_d] })
                        .title('D'),        
                      vl.tooltip([{ 'field': 'student_name', 'title': 'Sudent Name' },
                                  { 'field': 'd', 'title': 'D' },
                                  { 'field': 'e', 'title': 'E' }])
                                ).width(500).height(250);

  const hp = mpg.markLine({ color: '#227a15' })     
              .encode(
                      vl.y()
                        .fieldQ('e2')
                        .scale({ "domain": [0, max_y_scale_value_for_e] })
                        .title('E')
                     );

  const plot = vl.vconcat(
                       vl.layer(mpg, mpg.markCircle()),
                       vl.layer(hp, hp.markCircle({ color: '#227a15' }))
                     )

  return plot.toObject();
}

const chart_spec_json = this.createChart(data)
const opt = {
               renderer: "canvas",
               actions: false
            };
vegaEmbed("#stats", chart_spec_json, opt);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="https://unpkg.com/vega@5.21.0/build/vega.min.js"></script>
<script src="https://unpkg.com/vega-lite@5.2.0/build/vega-lite.min.js"></script>
<script src="https://www.unpkg.com/vega-embed@6.20.8/build/vega-embed.min.js"></script>
<script src="https://unpkg.com/vega-lite-api@5.0.0/build/vega-lite-api.min.js"></script>
<div id="stats" />

Run the above code to see how it gets rendered. This is how it looks: enter image description here

However, when I do the exact same with the same code and the same data (with only real student names), with same version of dependencies loaded in my development environment, it gets rendered like this:

enter image description here

Notice the weird horizontal spike in the line charts. It seems that one student is not getting correctly sorted in the order. But why this might be happening?


Solution

  • I guess you have duplicated student names in real data. I can replicate “broken” charts by changing student name in one of latter records with e=d=0 to one of previous names where e & d are greater than zero.