• Edit
  • Download
  • <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <title>ZingSoft Demo</title>
      <script nonce="undefined" src="https://cdn.zingchart.com/zingchart.min.js"></script>
      <style>
        .chart--container {
          min-height: 530px;
          width: 100%;
          height: 100%;
        }
    
        .zc-ref {
          display: none;
        }
      </style>
    </head>
    
    <body>
      <div id="myChart" class="chart--container">
        <a class="zc-ref" href="https://www.zingchart.com/">Powered by ZingChart</a>
      </div>
      <script>
        ZC.LICENSE = ["569d52cefae586f634c54f86dc99e6a9", "b55b025e438fa8a98e32482b5f768ff5"];
        let aColorRange = ['#D36A67', '#E5896C', '#F9BC7F', '#F9DEA7', '#9CD8B1', '#91BAA0', '#389B96', '#425B5E'];
        let aDomain = [100000, 40000000]; // [mix,max]
    
        let chartItems = {
          CA: {
            value: 38332521
          },
          OR: {
            value: 3930065
          },
          WA: {
            value: 6971406
          },
          NV: {
            value: 2790136
          },
          ID: {
            value: 1612136
          },
          UT: {
            value: 2900872
          },
          AZ: {
            value: 6626624
          },
          MT: {
            value: 1015165
          },
          WY: {
            value: 582658
          },
          CO: {
            value: 5268367
          },
          NM: {
            value: 2085287
          },
          AK: {
            value: 735132
          },
          HI: {
            value: 1404054
          },
          TX: {
            value: 26448193
          },
          OK: {
            value: 3850568
          },
          KS: {
            value: 2893957
          },
          NE: {
            value: 1868516
          },
          SD: {
            value: 844877
          },
          ND: {
            value: 723393
          },
          MN: {
            value: 5420380
          },
          IA: {
            value: 3090416
          },
          MO: {
            value: 6044171
          },
          AR: {
            value: 2959373
          },
          LA: {
            value: 4625470
          },
          MS: {
            value: 2991207
          },
          TN: {
            value: 6495978
          },
          KY: {
            value: 4395295
          },
          IL: {
            value: 12882135
          },
          WI: {
            value: 5742713
          },
          MI: {
            value: 9895622
          },
          IN: {
            value: 6570902
          },
          AL: {
            value: 4833722
          },
          GA: {
            value: 9992167
          },
          FL: {
            value: 19552860
          },
          SC: {
            value: 4774839
          },
          NC: {
            value: 9848060
          },
          VA: {
            value: 8260405
          },
          WV: {
            value: 1854304
          },
          OH: {
            value: 11570808
          },
          PA: {
            value: 12773801
          },
          DC: {
            value: 681170
          },
          MD: {
            value: 5928814
          },
          DE: {
            value: 925749
          },
          NJ: {
            value: 8899339
          },
          NY: {
            value: 19651127
          },
          CT: {
            value: 3596080
          },
          RI: {
            value: 1051511
          },
          MA: {
            value: 6692824
          },
          VT: {
            value: 626630
          },
          NH: {
            value: 1323459
          },
          ME: {
            value: 1328302
          }
        };
    
        let chartConfig = {
          title: {
            text: 'Population By Province',
            align: 'left',
            fontSize: '14px'
          },
          shapes: [{
            type: 'zingchart.maps',
            options: {
              name: 'usa',
              scale: {
                type: 'quantize', // if you define threshold here your domain length must match your range length
                domain: aDomain, // [min,max]
                range: aColorRange
              },
              style: {
                tooltip: {
                  backgroundColor: 'inherit',
                  borderColor: '#FFF',
                  borderWidth: '2px',
                  fontColor: '#000',
                  fontSize: '15px'
                },
                controls: {
                  placement: 'br'
                },
                hoverState: {
                  backgroundColor: 'transparent',
                  borderColor: '#000',
                  borderWidth: '2px'
                },
                items: chartItems,
                label: { // text displaying. Like valueBox
                  fontSize: '8px',
                  visible: true
                }
              },
              zoom: 1.1
            }
          }],
          choropleth: {
            legend: {
              align: 'left',
              verticalAlign: 'bottom',
              header: {
                text: 'Population Range'
              },
              item: {
                cursor: 'pointer',
              },
              items: [{
                text: ' > 100,000'
              }],
              marker: {
                cursor: 'pointer'
              }
            }
          }
        };
    
        zingchart.loadModules('maps,maps-usa');
        zingchart.render({
          id: 'myChart',
          modules: 'choropleth',
          data: chartConfig,
          height: '100%',
          width: '100%',
        });
    
        // Used to only bind events once. When the window re-sizes we don't need to overwrite the events
        let firstTimeLoad = true;
    
        let leftOrRight = (value, left, right) => {
          let leftDiff = Math.abs(value - left);
          let rightDiff = Math.abs(value - right);
          return leftDiff < rightDiff ? true : false
        };
    
        let isBetween = (value, left, right) => {
          return value > left && value < right;
        };
    
        let thresholdIndex = (value, scale) => {
          for (let i = 0; i < scale.length; i++) {
            if (value < scale[i]) {
              return i;
            }
          }
          return scale.length;
        };
    
        let quantizeIndex = (value, scale) => {
          let first = scale[0];
          let last = scale[scale.length - 1];
          for (let i = 0; i < scale.length; i++) {
            if (value <= first) {
              return 0;
            } else if (value >= last) {
              return scale.length - 1;
            } else if (i < scale.length - 1) {
              if (value == scale[i]) {
                return i;
              } else {
                let current = scale[i];
                let next = scale[i + 1];
                if (isBetween(value, current, next)) {
                  return leftOrRight(value, current, next) ? i : i + 1;
                }
              }
            }
          }
        };
    
        // define mix max for domain
        let quantize = (value, domain, range) => {
          let index = quantizeIndex(value, domain);
          return {
            range: range[index],
            domain: domain[index],
            group: index
          };
        };
    
        let quantizeDomain = (aDomain, aRange) => {
          let iMin = aDomain[0];
          let iMax = aDomain[1];
          let iSlope = (iMax - iMin) / (aRange.length - 1);
          let aScale = [];
          for (let i = 0; i < aRange.length; i++) {
            aScale[i] = (iSlope * i + iMin);
          }
          return aScale;
        };
    
        let generateDomain = (sType, aDomain, aRange) => {
          let aScale = aDomain;
          if (sType == 'quantize') {
            aScale = quantizeDomain(aDomain, aRange)
          }
          return aScale;
        };
    
        let drawLegend = (domain, range, json) => {
          if (!json.series)
            json.series = [];
    
          json.legend = json.choropleth.legend || {};
          for (let i = 0; i < domain.length; i++) {
            json.series[i] = {
              /* 
               * merge text if user wants to define new text.
               * else format thousands separator
               */
              text: (json.legend.items && json.legend.items[i] && json.legend.items[i].text) ? json.legend.items[i].text : Math.round(domain[i]).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','),
              lineColor: range[i],
              backgroundColor: range,
              dataDomain: domain[i],
              dataVisible: true
            };
          }
        };
    
        let legendClickForMaps = (e) => {
          let clickedDomain = e.xdata.domain;
          let plotIsVisible = e.xdata.visible;
          let plotIndex = e.plotindex;
          let json = zingchart.exec(e.id, 'getdata');
          json = json.graphset ? json.graphset[0] : json;
          let items = json.shapes;
          let toggleOffColor = '#c3c3c3';
          e.xdata.visible = !e.xdata.visible;
    
          for (let i = 0; i < items.length; i++) {
            if (clickedDomain == items[i].domain) {
              if (plotIsVisible) {
                items[i]['background-color'] = toggleOffColor;
              } else {
                items[i]['background-color'] = items[i]['original-background-color'];
              }
              zingchart.exec(e.id, 'updateobject', {
                type: 'shape',
                data: items[i]
              });
            }
          }
        };
    
        // define a range of thresholds for domain
        let threshold = (value, domain, range) => {
          let index = thresholdIndex(value, domain);
          return {
            range: range[index],
            domain: domain[index],
            group: index
          };
        };
    
        /* custom module for choropleth charts */
        zingchart.defineModule('choropleth', 'plugin', (originalJson) => {
          if (originalJson.shapes[0].options) {
            let options = originalJson.shapes[0].options;
            let mapType = options.name;
            let scaleType = options.scale.type;
            let range = options.scale.range;
            let domain = generateDomain(scaleType, options.scale.domain, range);
            let scaleFunction = (scaleType == 'quantize' ? quantize : threshold);
    
            // Initialize items object
            let items = {};
            // Iterate over options items
            for (let key in options.style.items) {
              let item = options.style.items[key];
              let name = item.name;
              let value = item.value;
              let rangeIndex = scaleFunction(value, domain, range);
              let keyInfo = zingchart.maps.getItemInfo(options.name, key)
              item['background-color'] = rangeIndex.range;
              item['original-background-color'] = rangeIndex.range;
              item['domain'] = rangeIndex.domain;
              item['tooltip'] = options.style.tooltip ? JSON.parse(JSON.stringify(options.style.tooltip)) : {};
              item['tooltip']['text'] = keyInfo.tooltip.text + ' <br>' + item.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
              item['group'] = rangeIndex.group + 1;
    
              // border color, font-color and background color can inherit
              if (item['tooltip']['border-color'] == 'inherit')
                item['tooltip']['border-color'] = rangeIndex.range;
              if (item['tooltip']['backgroundColor'] == 'inherit')
                item['tooltip']['backgroundColor'] = rangeIndex.range;
              if (item['tooltip']['background-color'] == 'inherit')
                item['tooltip']['background-color'] = rangeIndex.range;
              if (item['tooltip']['font-color'] == 'inherit')
                item['tooltip']['font-color'] = rangeIndex.range;
            }
    
            // Draw the legend
            if (originalJson.choropleth.legend) {
              drawLegend(domain, range, originalJson);
    
              // only bind events on first load
              if (firstTimeLoad) {
                zingchart.bind(null, 'legend_item_click', legendClickForMaps);
                zingchart.bind(null, 'legend_marker_click', legendClickForMaps);
                firstTimeLoad = false;
              }
            }
    
            return originalJson;
          } else {
            console.error('Whoa there... You need an `options` object to set the styles.');
          }
        });
      </script>
    </body>
    
    </html>
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <title>ZingSoft Demo</title>
      <script src="https://cdn.zingchart.com/zingchart.min.js"></script>
    </head>
    
    <body>
      <div id="myChart" class="chart--container">
        <a class="zc-ref" href="https://www.zingchart.com/">Powered by ZingChart</a>
      </div>
    </body>
    
    </html>
    .chart--container {
      min-height: 530px;
      width: 100%;
      height: 100%;
    }
    
    .zc-ref {
      display: none;
    }
    let aColorRange = ['#D36A67', '#E5896C', '#F9BC7F', '#F9DEA7', '#9CD8B1', '#91BAA0', '#389B96', '#425B5E'];
    let aDomain = [100000, 40000000]; // [mix,max]
    
    let chartItems = {
      CA: {
        value: 38332521
      },
      OR: {
        value: 3930065
      },
      WA: {
        value: 6971406
      },
      NV: {
        value: 2790136
      },
      ID: {
        value: 1612136
      },
      UT: {
        value: 2900872
      },
      AZ: {
        value: 6626624
      },
      MT: {
        value: 1015165
      },
      WY: {
        value: 582658
      },
      CO: {
        value: 5268367
      },
      NM: {
        value: 2085287
      },
      AK: {
        value: 735132
      },
      HI: {
        value: 1404054
      },
      TX: {
        value: 26448193
      },
      OK: {
        value: 3850568
      },
      KS: {
        value: 2893957
      },
      NE: {
        value: 1868516
      },
      SD: {
        value: 844877
      },
      ND: {
        value: 723393
      },
      MN: {
        value: 5420380
      },
      IA: {
        value: 3090416
      },
      MO: {
        value: 6044171
      },
      AR: {
        value: 2959373
      },
      LA: {
        value: 4625470
      },
      MS: {
        value: 2991207
      },
      TN: {
        value: 6495978
      },
      KY: {
        value: 4395295
      },
      IL: {
        value: 12882135
      },
      WI: {
        value: 5742713
      },
      MI: {
        value: 9895622
      },
      IN: {
        value: 6570902
      },
      AL: {
        value: 4833722
      },
      GA: {
        value: 9992167
      },
      FL: {
        value: 19552860
      },
      SC: {
        value: 4774839
      },
      NC: {
        value: 9848060
      },
      VA: {
        value: 8260405
      },
      WV: {
        value: 1854304
      },
      OH: {
        value: 11570808
      },
      PA: {
        value: 12773801
      },
      DC: {
        value: 681170
      },
      MD: {
        value: 5928814
      },
      DE: {
        value: 925749
      },
      NJ: {
        value: 8899339
      },
      NY: {
        value: 19651127
      },
      CT: {
        value: 3596080
      },
      RI: {
        value: 1051511
      },
      MA: {
        value: 6692824
      },
      VT: {
        value: 626630
      },
      NH: {
        value: 1323459
      },
      ME: {
        value: 1328302
      }
    };
    
    let chartConfig = {
      title: {
        text: 'Population By Province',
        align: 'left',
        fontSize: '14px'
      },
      shapes: [{
        type: 'zingchart.maps',
        options: {
          name: 'usa',
          scale: {
            type: 'quantize', // if you define threshold here your domain length must match your range length
            domain: aDomain, // [min,max]
            range: aColorRange
          },
          style: {
            tooltip: {
              backgroundColor: 'inherit',
              borderColor: '#FFF',
              borderWidth: '2px',
              fontColor: '#000',
              fontSize: '15px'
            },
            controls: {
              placement: 'br'
            },
            hoverState: {
              backgroundColor: 'transparent',
              borderColor: '#000',
              borderWidth: '2px'
            },
            items: chartItems,
            label: { // text displaying. Like valueBox
              fontSize: '8px',
              visible: true
            }
          },
          zoom: 1.1
        }
      }],
      choropleth: {
        legend: {
          align: 'left',
          verticalAlign: 'bottom',
          header: {
            text: 'Population Range'
          },
          item: {
            cursor: 'pointer',
          },
          items: [{
            text: ' > 100,000'
          }],
          marker: {
            cursor: 'pointer'
          }
        }
      }
    };
    
    zingchart.loadModules('maps,maps-usa');
    zingchart.render({
      id: 'myChart',
      modules: 'choropleth',
      data: chartConfig,
      height: '100%',
      width: '100%',
    });
    
    // Used to only bind events once. When the window re-sizes we don't need to overwrite the events
    let firstTimeLoad = true;
    
    let leftOrRight = (value, left, right) => {
      let leftDiff = Math.abs(value - left);
      let rightDiff = Math.abs(value - right);
      return leftDiff < rightDiff ? true : false
    };
    
    let isBetween = (value, left, right) => {
      return value > left && value < right;
    };
    
    let thresholdIndex = (value, scale) => {
      for (let i = 0; i < scale.length; i++) {
        if (value < scale[i]) {
          return i;
        }
      }
      return scale.length;
    };
    
    let quantizeIndex = (value, scale) => {
      let first = scale[0];
      let last = scale[scale.length - 1];
      for (let i = 0; i < scale.length; i++) {
        if (value <= first) {
          return 0;
        } else if (value >= last) {
          return scale.length - 1;
        } else if (i < scale.length - 1) {
          if (value == scale[i]) {
            return i;
          } else {
            let current = scale[i];
            let next = scale[i + 1];
            if (isBetween(value, current, next)) {
              return leftOrRight(value, current, next) ? i : i + 1;
            }
          }
        }
      }
    };
    
    // define mix max for domain
    let quantize = (value, domain, range) => {
      let index = quantizeIndex(value, domain);
      return {
        range: range[index],
        domain: domain[index],
        group: index
      };
    };
    
    let quantizeDomain = (aDomain, aRange) => {
      let iMin = aDomain[0];
      let iMax = aDomain[1];
      let iSlope = (iMax - iMin) / (aRange.length - 1);
      let aScale = [];
      for (let i = 0; i < aRange.length; i++) {
        aScale[i] = (iSlope * i + iMin);
      }
      return aScale;
    };
    
    let generateDomain = (sType, aDomain, aRange) => {
      let aScale = aDomain;
      if (sType == 'quantize') {
        aScale = quantizeDomain(aDomain, aRange)
      }
      return aScale;
    };
    
    let drawLegend = (domain, range, json) => {
      if (!json.series)
        json.series = [];
    
      json.legend = json.choropleth.legend || {};
      for (let i = 0; i < domain.length; i++) {
        json.series[i] = {
          /* 
           * merge text if user wants to define new text.
           * else format thousands separator
           */
          text: (json.legend.items && json.legend.items[i] && json.legend.items[i].text) ? json.legend.items[i].text : Math.round(domain[i]).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','),
          lineColor: range[i],
          backgroundColor: range,
          dataDomain: domain[i],
          dataVisible: true
        };
      }
    };
    
    let legendClickForMaps = (e) => {
      let clickedDomain = e.xdata.domain;
      let plotIsVisible = e.xdata.visible;
      let plotIndex = e.plotindex;
      let json = zingchart.exec(e.id, 'getdata');
      json = json.graphset ? json.graphset[0] : json;
      let items = json.shapes;
      let toggleOffColor = '#c3c3c3';
      e.xdata.visible = !e.xdata.visible;
    
      for (let i = 0; i < items.length; i++) {
        if (clickedDomain == items[i].domain) {
          if (plotIsVisible) {
            items[i]['background-color'] = toggleOffColor;
          } else {
            items[i]['background-color'] = items[i]['original-background-color'];
          }
          zingchart.exec(e.id, 'updateobject', {
            type: 'shape',
            data: items[i]
          });
        }
      }
    };
    
    // define a range of thresholds for domain
    let threshold = (value, domain, range) => {
      let index = thresholdIndex(value, domain);
      return {
        range: range[index],
        domain: domain[index],
        group: index
      };
    };
    
    /* custom module for choropleth charts */
    zingchart.defineModule('choropleth', 'plugin', (originalJson) => {
      if (originalJson.shapes[0].options) {
        let options = originalJson.shapes[0].options;
        let mapType = options.name;
        let scaleType = options.scale.type;
        let range = options.scale.range;
        let domain = generateDomain(scaleType, options.scale.domain, range);
        let scaleFunction = (scaleType == 'quantize' ? quantize : threshold);
    
        // Initialize items object
        let items = {};
        // Iterate over options items
        for (let key in options.style.items) {
          let item = options.style.items[key];
          let name = item.name;
          let value = item.value;
          let rangeIndex = scaleFunction(value, domain, range);
          let keyInfo = zingchart.maps.getItemInfo(options.name, key)
          item['background-color'] = rangeIndex.range;
          item['original-background-color'] = rangeIndex.range;
          item['domain'] = rangeIndex.domain;
          item['tooltip'] = options.style.tooltip ? JSON.parse(JSON.stringify(options.style.tooltip)) : {};
          item['tooltip']['text'] = keyInfo.tooltip.text + ' <br>' + item.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
          item['group'] = rangeIndex.group + 1;
    
          // border color, font-color and background color can inherit
          if (item['tooltip']['border-color'] == 'inherit')
            item['tooltip']['border-color'] = rangeIndex.range;
          if (item['tooltip']['backgroundColor'] == 'inherit')
            item['tooltip']['backgroundColor'] = rangeIndex.range;
          if (item['tooltip']['background-color'] == 'inherit')
            item['tooltip']['background-color'] = rangeIndex.range;
          if (item['tooltip']['font-color'] == 'inherit')
            item['tooltip']['font-color'] = rangeIndex.range;
        }
    
        // Draw the legend
        if (originalJson.choropleth.legend) {
          drawLegend(domain, range, originalJson);
    
          // only bind events on first load
          if (firstTimeLoad) {
            zingchart.bind(null, 'legend_item_click', legendClickForMaps);
            zingchart.bind(null, 'legend_marker_click', legendClickForMaps);
            firstTimeLoad = false;
          }
        }
    
        return originalJson;
      } else {
        console.error('Whoa there... You need an `options` object to set the styles.');
      }
    });